use of libcore.io.ErrnoException in project android_frameworks_base by ParanoidAndroid.
the class SharedPreferencesImpl method writeToFile.
// Note: must hold mWritingToDiskLock
private void writeToFile(MemoryCommitResult mcr) {
// Rename the current file so it may be used as a backup during the next read
if (mFile.exists()) {
if (!mcr.changesMade) {
// If the file already exists, but no changes were
// made to the underlying map, it's wasteful to
// re-write the file. Return as if we wrote it
// out.
mcr.setDiskWriteResult(true);
return;
}
if (!mBackupFile.exists()) {
if (!mFile.renameTo(mBackupFile)) {
Log.e(TAG, "Couldn't rename file " + mFile + " to backup file " + mBackupFile);
mcr.setDiskWriteResult(false);
return;
}
} else {
mFile.delete();
}
}
// from the backup.
try {
FileOutputStream str = createFileOutputStream(mFile);
if (str == null) {
mcr.setDiskWriteResult(false);
return;
}
XmlUtils.writeMapXml(mcr.mapToWriteToDisk, str);
FileUtils.sync(str);
str.close();
ContextImpl.setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
try {
final StructStat stat = Libcore.os.stat(mFile.getPath());
synchronized (this) {
mStatTimestamp = stat.st_mtime;
mStatSize = stat.st_size;
}
} catch (ErrnoException e) {
// Do nothing
}
// Writing was successful, delete the backup file if there is one.
mBackupFile.delete();
mcr.setDiskWriteResult(true);
return;
} catch (XmlPullParserException e) {
Log.w(TAG, "writeToFile: Got exception:", e);
} catch (IOException e) {
Log.w(TAG, "writeToFile: Got exception:", e);
}
// Clean up an unsuccessfully written file
if (mFile.exists()) {
if (!mFile.delete()) {
Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
}
}
mcr.setDiskWriteResult(false);
}
use of libcore.io.ErrnoException in project android_frameworks_base by ParanoidAndroid.
the class ZygoteConnection method runOnce.
/**
* Reads one start command from the command socket. If successful,
* a child is forked and a {@link ZygoteInit.MethodAndArgsCaller}
* exception is thrown in that child while in the parent process,
* the method returns normally. On failure, the child is not
* spawned and messages are printed to the log and stderr. Returns
* a boolean status value indicating whether an end-of-file on the command
* socket has been encountered.
*
* @return false if command socket should continue to be read from, or
* true if an end-of-file has been encountered.
* @throws ZygoteInit.MethodAndArgsCaller trampoline to invoke main()
* method in child process
*/
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
String[] args;
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
Log.w(TAG, "IOException on command socket " + ex.getMessage());
closeSocket();
return true;
}
if (args == null) {
// EOF reached.
closeSocket();
return true;
}
/** the stderr of the most recent request, if avail */
PrintStream newStderr = null;
if (descriptors != null && descriptors.length >= 3) {
newStderr = new PrintStream(new FileOutputStream(descriptors[2]));
}
int pid = -1;
FileDescriptor childPipeFd = null;
FileDescriptor serverPipeFd = null;
try {
parsedArgs = new Arguments(args);
applyUidSecurityPolicy(parsedArgs, peer, peerSecurityContext);
applyRlimitSecurityPolicy(parsedArgs, peer, peerSecurityContext);
applyCapabilitiesSecurityPolicy(parsedArgs, peer, peerSecurityContext);
applyInvokeWithSecurityPolicy(parsedArgs, peer, peerSecurityContext);
applyseInfoSecurityPolicy(parsedArgs, peer, peerSecurityContext);
applyDebuggerSystemProperty(parsedArgs);
applyInvokeWithSystemProperty(parsedArgs);
int[][] rlimits = null;
if (parsedArgs.rlimits != null) {
rlimits = parsedArgs.rlimits.toArray(intArray2d);
}
if (parsedArgs.runtimeInit && parsedArgs.invokeWith != null) {
FileDescriptor[] pipeFds = Libcore.os.pipe();
childPipeFd = pipeFds[1];
serverPipeFd = pipeFds[0];
ZygoteInit.setCloseOnExec(serverPipeFd, true);
}
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName);
} catch (IOException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
} catch (ErrnoException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
} catch (IllegalArgumentException ex) {
logAndPrintError(newStderr, "Invalid zygote arguments", ex);
} catch (ZygoteSecurityException ex) {
logAndPrintError(newStderr, "Zygote security policy prevents request: ", ex);
}
try {
if (pid == 0) {
// in child
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
// throw ZygoteInit.MethodAndArgsCaller or exec().
return true;
} else {
// in parent...pid of < 0 means failure
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
use of libcore.io.ErrnoException in project android_frameworks_base by ParanoidAndroid.
the class DefaultContainerService method copyResourceInner.
private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName, String publicResFileName, boolean isExternal, boolean isForwardLocked) {
if (isExternal) {
// Make sure the sdcard is mounted.
String status = Environment.getExternalStorageState();
if (!status.equals(Environment.MEDIA_MOUNTED)) {
Slog.w(TAG, "Make sure sdcard is mounted.");
return null;
}
}
// The .apk file
String codePath = packageURI.getPath();
File codeFile = new File(codePath);
// Calculate size of container needed to hold base APK.
final int sizeMb;
try {
sizeMb = calculateContainerSize(codeFile, isForwardLocked);
} catch (IOException e) {
Slog.w(TAG, "Problem when trying to copy " + codeFile.getPath());
return null;
}
// Create new container
final String newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid(), isExternal);
if (newCachePath == null) {
Slog.e(TAG, "Failed to create container " + newCid);
return null;
}
if (localLOGV) {
Slog.i(TAG, "Created container for " + newCid + " at path : " + newCachePath);
}
final File resFile = new File(newCachePath, resFileName);
if (FileUtils.copyFile(new File(codePath), resFile)) {
if (localLOGV) {
Slog.i(TAG, "Copied " + codePath + " to " + resFile);
}
} else {
Slog.e(TAG, "Failed to copy " + codePath + " to " + resFile);
// Clean up container
PackageHelper.destroySdDir(newCid);
return null;
}
try {
Libcore.os.chmod(resFile.getAbsolutePath(), 0640);
} catch (ErrnoException e) {
Slog.e(TAG, "Could not chown APK: " + e.getMessage());
PackageHelper.destroySdDir(newCid);
return null;
}
if (isForwardLocked) {
File publicZipFile = new File(newCachePath, publicResFileName);
try {
PackageHelper.extractPublicFiles(resFile.getAbsolutePath(), publicZipFile);
if (localLOGV) {
Slog.i(TAG, "Copied resources to " + publicZipFile);
}
} catch (IOException e) {
Slog.e(TAG, "Could not chown public APK " + publicZipFile.getAbsolutePath() + ": " + e.getMessage());
PackageHelper.destroySdDir(newCid);
return null;
}
try {
Libcore.os.chmod(publicZipFile.getAbsolutePath(), 0644);
} catch (ErrnoException e) {
Slog.e(TAG, "Could not chown public resource file: " + e.getMessage());
PackageHelper.destroySdDir(newCid);
return null;
}
}
final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME);
if (sharedLibraryDir.mkdir()) {
int ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(codeFile, sharedLibraryDir);
if (ret != PackageManager.INSTALL_SUCCEEDED) {
Slog.e(TAG, "Could not copy native libraries to " + sharedLibraryDir.getPath());
PackageHelper.destroySdDir(newCid);
return null;
}
} else {
Slog.e(TAG, "Could not create native lib directory: " + sharedLibraryDir.getPath());
PackageHelper.destroySdDir(newCid);
return null;
}
if (!PackageHelper.finalizeSdDir(newCid)) {
Slog.e(TAG, "Failed to finalize " + newCid + " at path " + newCachePath);
// Clean up container
PackageHelper.destroySdDir(newCid);
return null;
}
if (localLOGV) {
Slog.i(TAG, "Finalized container " + newCid);
}
if (PackageHelper.isContainerMounted(newCid)) {
if (localLOGV) {
Slog.i(TAG, "Unmounting " + newCid + " at path " + newCachePath);
}
// Force a gc to avoid being killed.
Runtime.getRuntime().gc();
PackageHelper.unMountSdDir(newCid);
} else {
if (localLOGV) {
Slog.i(TAG, "Container " + newCid + " not mounted");
}
}
return newCachePath;
}
use of libcore.io.ErrnoException in project android_frameworks_base by ParanoidAndroid.
the class PackageManagerService method scanPackageLI.
private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, long currentTime, UserHandle user) {
File scanFile = new File(pkg.mScanPath);
if (scanFile == null || pkg.applicationInfo.sourceDir == null || pkg.applicationInfo.publicSourceDir == null) {
// Bail out. The resource and code paths haven't been set.
Slog.w(TAG, " Code and resource paths haven't been set correctly");
mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
return null;
}
mScanningPath = scanFile;
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
}
if (pkg.packageName.equals("android")) {
synchronized (mPackages) {
if (mAndroidApplication != null) {
Slog.w(TAG, "*************************************************");
Slog.w(TAG, "Core android package being redefined. Skipping.");
Slog.w(TAG, " file=" + mScanningPath);
Slog.w(TAG, "*************************************************");
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
}
// Set up information for our fall-back user intent resolution
// activity.
mPlatformPackage = pkg;
pkg.mVersionCode = mSdkVersion;
mAndroidApplication = pkg.applicationInfo;
mResolveActivity.applicationInfo = mAndroidApplication;
mResolveActivity.name = ResolverActivity.class.getName();
mResolveActivity.packageName = mAndroidApplication.packageName;
mResolveActivity.processName = "system:ui";
mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
mResolveActivity.exported = true;
mResolveActivity.enabled = true;
mResolveInfo.activityInfo = mResolveActivity;
mResolveInfo.priority = 0;
mResolveInfo.preferredOrder = 0;
mResolveInfo.match = 0;
mResolveComponentName = new ComponentName(mAndroidApplication.packageName, mResolveActivity.name);
}
}
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
Log.d(TAG, "Scanning package " + pkg.packageName);
}
if (mPackages.containsKey(pkg.packageName) || mSharedLibraries.containsKey(pkg.packageName)) {
Slog.w(TAG, "Application package " + pkg.packageName + " already installed. Skipping duplicate.");
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
}
if (!pkg.applicationInfo.sourceDir.startsWith(Environment.getRootDirectory().getPath()) && !pkg.applicationInfo.sourceDir.startsWith("/vendor")) {
Object obj = mSettings.getUserIdLPr(1000);
Signature[] s1 = null;
if (obj instanceof SharedUserSetting) {
s1 = ((SharedUserSetting) obj).signatures.mSignatures;
}
if ((compareSignatures(pkg.mSignatures, s1) == PackageManager.SIGNATURE_MATCH)) {
Slog.w(TAG, "Cannot install platform packages to user storage");
mLastScanError = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
return null;
}
}
// Initialize package source and resource directories
File destCodeFile = new File(pkg.applicationInfo.sourceDir);
File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
SharedUserSetting suid = null;
PackageSetting pkgSetting = null;
if (!isSystemApp(pkg)) {
// Only system apps can use these features.
pkg.mOriginalPackages = null;
pkg.mRealPackage = null;
pkg.mAdoptPermissions = null;
}
// writer
synchronized (mPackages) {
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
// library paths after the scan is done.
if (!updateSharedLibrariesLPw(pkg, null)) {
return null;
}
}
if (pkg.mSharedUserId != null) {
suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, pkg.applicationInfo.flags, true);
if (suid == null) {
Slog.w(TAG, "Creating application package " + pkg.packageName + " for shared user failed");
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId + "): packages=" + suid.packages);
}
}
// Check if we are renaming from an original package name.
PackageSetting origPackage = null;
String realName = null;
if (pkg.mOriginalPackages != null) {
// This package may need to be renamed to a previously
// installed name. Let's check on that...
final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
if (pkg.mOriginalPackages.contains(renamed)) {
// This package had originally been installed as the
// original name, and we have already taken care of
// transitioning to the new one. Just update the new
// one to continue using the old name.
realName = pkg.mRealPackage;
if (!pkg.packageName.equals(renamed)) {
// Callers into this function may have already taken
// care of renaming the package; only do it here if
// it is not already done.
pkg.setPackageName(renamed);
}
} else {
for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; i--) {
if ((origPackage = mSettings.peekPackageLPr(pkg.mOriginalPackages.get(i))) != null) {
// original name... should we use it?
if (!verifyPackageUpdateLPr(origPackage, pkg)) {
// New package is not compatible with original.
origPackage = null;
continue;
} else if (origPackage.sharedUser != null) {
// Make sure uid is compatible between packages.
if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
Slog.w(TAG, "Unable to migrate data from " + origPackage.name + " to " + pkg.packageName + ": old uid " + origPackage.sharedUser.name + " differs from " + pkg.mSharedUserId);
origPackage = null;
continue;
}
} else {
if (DEBUG_UPGRADE)
Log.v(TAG, "Renaming new package " + pkg.packageName + " to old name " + origPackage.name);
}
break;
}
}
}
}
if (mTransferedPackages.contains(pkg.packageName)) {
Slog.w(TAG, "Package " + pkg.packageName + " was transferred to another, but its .apk remains");
}
// Just create the setting, don't add it yet. For already existing packages
// the PkgSetting exists already and doesn't have to be created.
pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.flags, user, false);
if (pkgSetting == null) {
Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
if (pkgSetting.origPackage != null) {
// If we are first transitioning from an original package,
// fix up the new package's name now. We need to do this after
// looking up the package under its new name, so getPackageLP
// can take care of fiddling things correctly.
pkg.setPackageName(origPackage.name);
// File a report about this.
String msg = "New package " + pkgSetting.realName + " renamed to replace old package " + pkgSetting.name;
reportSettingsProblem(Log.WARN, msg);
// Make a note of it.
mTransferedPackages.add(origPackage.name);
// No longer need to retain this.
pkgSetting.origPackage = null;
}
if (realName != null) {
// Make a note of it.
mTransferedPackages.add(pkg.packageName);
}
if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
if (mFoundPolicyFile) {
SELinuxMMAC.assignSeinfoValue(pkg);
}
pkg.applicationInfo.uid = pkgSetting.appId;
pkg.mExtras = pkgSetting;
if (!verifySignaturesLP(pkgSetting, pkg)) {
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
return null;
}
// The signature has changed, but this package is in the system
// image... let's recover!
pkgSetting.signatures.mSignatures = pkg.mSignatures;
// that unreasonable.
if (pkgSetting.sharedUser != null) {
if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
return null;
}
}
// File a report about this.
String msg = "System package " + pkg.packageName + " signature changed; retaining data.";
reportSettingsProblem(Log.WARN, msg);
}
// things that are installed.
if ((scanMode & SCAN_NEW_INSTALL) != 0) {
final int N = pkg.providers.size();
int i;
for (i = 0; i < N; i++) {
PackageParser.Provider p = pkg.providers.get(i);
if (p.info.authority != null) {
String[] names = p.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
if (mProviders.containsKey(names[j])) {
PackageParser.Provider other = mProviders.get(names[j]);
Slog.w(TAG, "Can't install because provider name " + names[j] + " (in package " + pkg.applicationInfo.packageName + ") is already used by " + ((other != null && other.getComponentName() != null) ? other.getComponentName().getPackageName() : "?"));
mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
return null;
}
}
}
}
}
if (pkg.mAdoptPermissions != null) {
// another package.
for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
final String origName = pkg.mAdoptPermissions.get(i);
final PackageSetting orig = mSettings.peekPackageLPr(origName);
if (orig != null) {
if (verifyPackageUpdateLPr(orig, pkg)) {
Slog.i(TAG, "Adopting permissions from " + origName + " to " + pkg.packageName);
mSettings.transferPermissionsLPw(origName, pkg.packageName);
}
}
}
}
}
final String pkgName = pkg.packageName;
final long scanFileTime = scanFile.lastModified();
final boolean forceDex = (scanMode & SCAN_FORCE_DEX) != 0;
pkg.applicationInfo.processName = fixProcessName(pkg.applicationInfo.packageName, pkg.applicationInfo.processName, pkg.applicationInfo.uid);
File dataPath;
if (mPlatformPackage == pkg) {
// The system package is special.
dataPath = new File(Environment.getDataDirectory(), "system");
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
// This is a normal package, need to make its data directory.
dataPath = getDataPathForPackage(pkg.packageName, 0);
boolean uidError = false;
if (dataPath.exists()) {
int currentUid = 0;
try {
StructStat stat = Libcore.os.stat(dataPath.getPath());
currentUid = stat.st_uid;
} catch (ErrnoException e) {
Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
}
// If we have mismatched owners for the data path, we have a problem.
if (currentUid != pkg.applicationInfo.uid) {
boolean recovered = false;
if (currentUid == 0) {
// The directory somehow became owned by root. Wow.
// This is probably because the system was stopped while
// installd was in the middle of messing with its libs
// directory. Ask installd to fix that.
int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid, pkg.applicationInfo.uid);
if (ret >= 0) {
recovered = true;
String msg = "Package " + pkg.packageName + " unexpectedly changed to uid 0; recovered to " + +pkg.applicationInfo.uid;
reportSettingsProblem(Log.WARN, msg);
}
}
if (!recovered && ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0 || (scanMode & SCAN_BOOTING) != 0)) {
// If this is a system app, we can at least delete its
// current data so the application will still work.
int ret = removeDataDirsLI(pkgName);
if (ret >= 0) {
// TODO: Kill the processes first
// Old data gone!
String prefix = (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0 ? "System package " : "Third party package ";
String msg = prefix + pkg.packageName + " has changed from uid: " + currentUid + " to " + pkg.applicationInfo.uid + "; old data erased";
reportSettingsProblem(Log.WARN, msg);
recovered = true;
// And now re-install the app.
ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, pkg.applicationInfo.seinfo);
if (ret == -1) {
// Ack should not happen!
msg = prefix + pkg.packageName + " could not have data directory re-created after delete.";
reportSettingsProblem(Log.WARN, msg);
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
}
if (!recovered) {
mHasSystemUidErrors = true;
}
} else if (!recovered) {
// If we allow this install to proceed, we will be broken.
// Abort, abort!
mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
return null;
}
if (!recovered) {
pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" + pkg.applicationInfo.uid + "/fs_" + currentUid;
pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
String msg = "Package " + pkg.packageName + " has mismatched uid: " + currentUid + " on disk, " + pkg.applicationInfo.uid + " in settings";
// writer
synchronized (mPackages) {
mSettings.mReadMessages.append(msg);
mSettings.mReadMessages.append('\n');
uidError = true;
if (!pkgSetting.uidError) {
reportSettingsProblem(Log.ERROR, msg);
}
}
}
}
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
Log.v(TAG, "Want this data dir: " + dataPath);
}
//invoke installer to do the actual installation
int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, pkg.applicationInfo.seinfo);
if (ret < 0) {
// Error from installer
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
if (dataPath.exists()) {
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
Slog.w(TAG, "Unable to create data directory: " + dataPath);
pkg.applicationInfo.dataDir = null;
}
}
/*
* Set the data dir to the default "/data/data/<package name>/lib"
* if we got here without anyone telling us different (e.g., apps
* stored on SD card have their native libraries stored in the ASEC
* container with the APK).
*
* This happens during an upgrade from a package settings file that
* doesn't have a native library path attribute at all.
*/
if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
if (pkgSetting.nativeLibraryPathString == null) {
setInternalAppNativeLibraryPath(pkg, pkgSetting);
} else {
pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
}
}
pkgSetting.uidError = uidError;
}
String path = scanFile.getPath();
/* Note: We don't want to unpack the native binaries for
* system applications, unless they have been updated
* (the binaries are already under /system/lib).
* Also, don't unpack libs for apps on the external card
* since they should have their libraries in the ASEC
* container already.
*
* In other words, we're going to unpack the binaries
* only for non-system apps and system app upgrades.
*/
if (pkg.applicationInfo.nativeLibraryDir != null) {
try {
File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
final String dataPathString = dataPath.getCanonicalPath();
if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
/*
* Upgrading from a previous version of the OS sometimes
* leaves native libraries in the /data/data/<app>/lib
* directory for system apps even when they shouldn't be.
* Recent changes in the JNI library search path
* necessitates we remove those to match previous behavior.
*/
if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
Log.i(TAG, "removed obsolete native libraries for system package " + path);
}
} else {
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
/*
* Update native library dir if it starts with
* /data/data
*/
if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
setInternalAppNativeLibraryPath(pkg, pkgSetting);
nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
}
try {
if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
Slog.e(TAG, "Unable to copy native libraries");
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
return null;
}
} catch (IOException e) {
Slog.e(TAG, "Unable to copy native libraries", e);
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
return null;
}
}
if (DEBUG_INSTALL)
Slog.i(TAG, "Linking native library dir for " + path);
final int[] userIds = sUserManager.getUserIds();
synchronized (mInstallLock) {
for (int userId : userIds) {
if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, pkg.applicationInfo.nativeLibraryDir, userId) < 0) {
Slog.w(TAG, "Failed linking native library dir (user=" + userId + ")");
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
return null;
}
}
}
}
} catch (IOException ioe) {
Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
}
}
pkg.mScanPath = path;
if ((scanMode & SCAN_NO_DEX) == 0) {
if (performDexOptLI(pkg, forceDex, (scanMode & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
return null;
}
}
if (mFactoryTest && pkg.requestedPermissions.contains(android.Manifest.permission.FACTORY_TEST)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
}
ArrayList<PackageParser.Package> clientLibPkgs = null;
// writer
synchronized (mPackages) {
if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
// Only system apps can add new shared libraries.
if (pkg.libraryNames != null) {
for (int i = 0; i < pkg.libraryNames.size(); i++) {
String name = pkg.libraryNames.get(i);
boolean allowed = false;
if (isUpdatedSystemApp(pkg)) {
// New library entries can only be added through the
// system image. This is important to get rid of a lot
// of nasty edge cases: for example if we allowed a non-
// system update of the app to add a library, then uninstalling
// the update would make the library go away, and assumptions
// we made such as through app install filtering would now
// have allowed apps on the device which aren't compatible
// with it. Better to just have the restriction here, be
// conservative, and create many fewer cases that can negatively
// impact the user experience.
final PackageSetting sysPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
if (name.equals(sysPs.pkg.libraryNames.get(j))) {
allowed = true;
allowed = true;
break;
}
}
}
} else {
allowed = true;
}
if (allowed) {
if (!mSharedLibraries.containsKey(name)) {
mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
} else if (!name.equals(pkg.packageName)) {
Slog.w(TAG, "Package " + pkg.packageName + " library " + name + " already exists; skipping");
}
} else {
Slog.w(TAG, "Package " + pkg.packageName + " declares lib " + name + " that is not declared on system image; skipping");
}
}
if ((scanMode & SCAN_BOOTING) == 0) {
// If we are not booting, we need to update any applications
// that are clients of our shared library. If we are booting,
// this will all be done once the scan is complete.
clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
}
}
}
}
// result in some apps being broken.
if (clientLibPkgs != null) {
if ((scanMode & SCAN_NO_DEX) == 0) {
for (int i = 0; i < clientLibPkgs.size(); i++) {
PackageParser.Package clientPkg = clientLibPkgs.get(i);
if (performDexOptLI(clientPkg, forceDex, (scanMode & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
return null;
}
}
}
}
// version of the application while the new one gets installed.
if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
killApplication(pkg.applicationInfo.packageName, pkg.applicationInfo.uid);
}
// Also need to kill any apps that are dependent on the library.
if (clientLibPkgs != null) {
for (int i = 0; i < clientLibPkgs.size(); i++) {
PackageParser.Package clientPkg = clientLibPkgs.get(i);
killApplication(clientPkg.applicationInfo.packageName, clientPkg.applicationInfo.uid);
}
}
// writer
synchronized (mPackages) {
// We don't expect installation to fail beyond this point,
if ((scanMode & SCAN_MONITOR) != 0) {
mAppDirs.put(pkg.mPath, pkg);
}
// Add the new setting to mSettings
mSettings.insertPackageSettingLPw(pkgSetting, pkg);
// Add the new setting to mPackages
mPackages.put(pkg.applicationInfo.packageName, pkg);
// Make sure we don't accidentally delete its data.
final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
while (iter.hasNext()) {
PackageCleanItem item = iter.next();
if (pkgName.equals(item.packageName)) {
iter.remove();
}
}
// Take care of first install / last update times.
if (currentTime != 0) {
if (pkgSetting.firstInstallTime == 0) {
pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
} else if ((scanMode & SCAN_UPDATE_TIME) != 0) {
pkgSetting.lastUpdateTime = currentTime;
}
} else if (pkgSetting.firstInstallTime == 0) {
// We need *something*. Take time time stamp of the file.
pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
} else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
if (scanFileTime != pkgSetting.timeStamp) {
// A package on the system image has changed; consider this
// to be an update.
pkgSetting.lastUpdateTime = scanFileTime;
}
}
int N = pkg.providers.size();
StringBuilder r = null;
int i;
for (i = 0; i < N; i++) {
PackageParser.Provider p = pkg.providers.get(i);
p.info.processName = fixProcessName(pkg.applicationInfo.processName, p.info.processName, pkg.applicationInfo.uid);
mProvidersByComponent.put(new ComponentName(p.info.packageName, p.info.name), p);
p.syncable = p.info.isSyncable;
if (p.info.authority != null) {
String[] names = p.info.authority.split(";");
p.info.authority = null;
for (int j = 0; j < names.length; j++) {
if (j == 1 && p.syncable) {
// We only want the first authority for a provider to possibly be
// syncable, so if we already added this provider using a different
// authority clear the syncable flag. We copy the provider before
// changing it because the mProviders object contains a reference
// to a provider that we don't want to change.
// Only do this for the second authority since the resulting provider
// object can be the same for all future authorities for this provider.
p = new PackageParser.Provider(p);
p.syncable = false;
}
if (!mProviders.containsKey(names[j])) {
mProviders.put(names[j], p);
if (p.info.authority == null) {
p.info.authority = names[j];
} else {
p.info.authority = p.info.authority + ";" + names[j];
}
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
Log.d(TAG, "Registered content provider: " + names[j] + ", className = " + p.info.name + ", isSyncable = " + p.info.isSyncable);
}
} else {
PackageParser.Provider other = mProviders.get(names[j]);
Slog.w(TAG, "Skipping provider name " + names[j] + " (in package " + pkg.applicationInfo.packageName + "): name already used by " + ((other != null && other.getComponentName() != null) ? other.getComponentName().getPackageName() : "?"));
}
}
}
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(p.info.name);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING)
Log.d(TAG, " Providers: " + r);
}
N = pkg.services.size();
r = null;
for (i = 0; i < N; i++) {
PackageParser.Service s = pkg.services.get(i);
s.info.processName = fixProcessName(pkg.applicationInfo.processName, s.info.processName, pkg.applicationInfo.uid);
mServices.addService(s);
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(s.info.name);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING)
Log.d(TAG, " Services: " + r);
}
N = pkg.receivers.size();
r = null;
for (i = 0; i < N; i++) {
PackageParser.Activity a = pkg.receivers.get(i);
a.info.processName = fixProcessName(pkg.applicationInfo.processName, a.info.processName, pkg.applicationInfo.uid);
mReceivers.addActivity(a, "receiver");
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING)
Log.d(TAG, " Receivers: " + r);
}
N = pkg.activities.size();
r = null;
for (i = 0; i < N; i++) {
PackageParser.Activity a = pkg.activities.get(i);
a.info.processName = fixProcessName(pkg.applicationInfo.processName, a.info.processName, pkg.applicationInfo.uid);
mActivities.addActivity(a, "activity");
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING)
Log.d(TAG, " Activities: " + r);
}
N = pkg.permissionGroups.size();
r = null;
for (i = 0; i < N; i++) {
PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
if (cur == null) {
mPermissionGroups.put(pg.info.name, pg);
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(pg.info.name);
}
} else {
Slog.w(TAG, "Permission group " + pg.info.name + " from package " + pg.info.packageName + " ignored: original from " + cur.info.packageName);
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append("DUP:");
r.append(pg.info.name);
}
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING)
Log.d(TAG, " Permission Groups: " + r);
}
N = pkg.permissions.size();
r = null;
for (i = 0; i < N; i++) {
PackageParser.Permission p = pkg.permissions.get(i);
HashMap<String, BasePermission> permissionMap = p.tree ? mSettings.mPermissionTrees : mSettings.mPermissions;
p.group = mPermissionGroups.get(p.info.group);
if (p.info.group == null || p.group != null) {
BasePermission bp = permissionMap.get(p.info.name);
if (bp == null) {
bp = new BasePermission(p.info.name, p.info.packageName, BasePermission.TYPE_NORMAL);
permissionMap.put(p.info.name, bp);
}
if (bp.perm == null) {
if (bp.sourcePackage == null || bp.sourcePackage.equals(p.info.packageName)) {
BasePermission tree = findPermissionTreeLP(p.info.name);
if (tree == null || tree.sourcePackage.equals(p.info.packageName)) {
bp.packageSetting = pkgSetting;
bp.perm = p;
bp.uid = pkg.applicationInfo.uid;
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(p.info.name);
}
} else {
Slog.w(TAG, "Permission " + p.info.name + " from package " + p.info.packageName + " ignored: base tree " + tree.name + " is from package " + tree.sourcePackage);
}
} else {
Slog.w(TAG, "Permission " + p.info.name + " from package " + p.info.packageName + " ignored: original from " + bp.sourcePackage);
}
} else if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append("DUP:");
r.append(p.info.name);
}
if (bp.perm == p) {
bp.protectionLevel = p.info.protectionLevel;
}
} else {
Slog.w(TAG, "Permission " + p.info.name + " from package " + p.info.packageName + " ignored: no group " + p.group);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING)
Log.d(TAG, " Permissions: " + r);
}
N = pkg.instrumentation.size();
r = null;
for (i = 0; i < N; i++) {
PackageParser.Instrumentation a = pkg.instrumentation.get(i);
a.info.packageName = pkg.applicationInfo.packageName;
a.info.sourceDir = pkg.applicationInfo.sourceDir;
a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
a.info.dataDir = pkg.applicationInfo.dataDir;
a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
mInstrumentation.put(a.getComponentName(), a);
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING)
Log.d(TAG, " Instrumentation: " + r);
}
if (pkg.protectedBroadcasts != null) {
N = pkg.protectedBroadcasts.size();
for (i = 0; i < N; i++) {
mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
}
}
pkgSetting.setTimeStamp(scanFileTime);
}
return pkg;
}
use of libcore.io.ErrnoException in project robovm by robovm.
the class OpenSSLSocketImpl method setSoWriteTimeout.
/**
* Note write timeouts are not part of the javax.net.ssl.SSLSocket API
*/
public void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
this.writeTimeoutMilliseconds = writeTimeoutMilliseconds;
StructTimeval tv = StructTimeval.fromMillis(writeTimeoutMilliseconds);
try {
Libcore.os.setsockoptTimeval(getFileDescriptor$(), SOL_SOCKET, SO_SNDTIMEO, tv);
} catch (ErrnoException errnoException) {
throw errnoException.rethrowAsSocketException();
}
}
Aggregations