diff options
Diffstat (limited to 'services/java/com')
3 files changed, 130 insertions, 30 deletions
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index cd58b9b..7c6d3c1 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -39,6 +39,7 @@ import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageDataObserver; +import android.content.pm.IPackageDeleteObserver; import android.content.pm.IPackageInstallObserver; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; @@ -1709,6 +1710,16 @@ class BackupManagerService extends IBackupManager.Stub { } } + // Cull any packages that have indicated that backups are not permitted. + for (int i = 0; i < packagesToBackup.size(); ) { + PackageInfo info = packagesToBackup.get(i); + if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) { + packagesToBackup.remove(i); + } else { + i++; + } + } + // Now back up the app data via the agent mechanism PackageInfo pkg = null; try { @@ -1937,7 +1948,6 @@ class BackupManagerService extends IBackupManager.Stub { // Which packages we've already wiped data on. We prepopulate this // with a whitelist of packages known to be unclearable. mClearedPackages.add("android"); - mClearedPackages.add("com.android.backupconfirm"); mClearedPackages.add("com.android.providers.settings"); } @@ -2314,6 +2324,7 @@ class BackupManagerService extends IBackupManager.Stub { class RestoreInstallObserver extends IPackageInstallObserver.Stub { final AtomicBoolean mDone = new AtomicBoolean(); + String mPackageName; int mResult; public void reset() { @@ -2341,12 +2352,45 @@ class BackupManagerService extends IBackupManager.Stub { throws RemoteException { synchronized (mDone) { mResult = returnCode; + mPackageName = packageName; mDone.set(true); mDone.notifyAll(); } } } + + class RestoreDeleteObserver extends IPackageDeleteObserver.Stub { + final AtomicBoolean mDone = new AtomicBoolean(); + int mResult; + + public void reset() { + synchronized (mDone) { + mDone.set(false); + } + } + + public void waitForCompletion() { + synchronized (mDone) { + while (mDone.get() == false) { + try { + mDone.wait(); + } catch (InterruptedException e) { } + } + } + } + + @Override + public void packageDeleted(String packageName, int returnCode) throws RemoteException { + synchronized (mDone) { + mResult = returnCode; + mDone.set(true); + mDone.notifyAll(); + } + } + } + final RestoreInstallObserver mInstallObserver = new RestoreInstallObserver(); + final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver(); boolean installApk(FileMetadata info, String installerPackage, InputStream instream) { boolean okay = true; @@ -2385,6 +2429,49 @@ class BackupManagerService extends IBackupManager.Stub { if (mPackagePolicies.get(info.packageName) != RestorePolicy.ACCEPT) { okay = false; } + } else { + // Okay, the install succeeded. Make sure it was the right app. + boolean uninstall = false; + if (!mInstallObserver.mPackageName.equals(info.packageName)) { + Slog.w(TAG, "Restore stream claimed to include apk for " + + info.packageName + " but apk was really " + + mInstallObserver.mPackageName); + // delete the package we just put in place; it might be fraudulent + okay = false; + uninstall = true; + } else { + try { + PackageInfo pkg = mPackageManager.getPackageInfo(info.packageName, + PackageManager.GET_SIGNATURES); + if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) { + Slog.w(TAG, "Restore stream contains apk of package " + + info.packageName + " but it disallows backup/restore"); + okay = false; + } else { + // So far so good -- do the signatures match the manifest? + Signature[] sigs = mManifestSignatures.get(info.packageName); + if (!signaturesMatch(sigs, pkg)) { + Slog.w(TAG, "Installed app " + info.packageName + + " signatures do not match restore manifest"); + okay = false; + uninstall = true; + } + } + } catch (NameNotFoundException e) { + Slog.w(TAG, "Install of package " + info.packageName + + " succeeded but now not found"); + okay = false; + } + } + + // If we're not okay at this point, we need to delete the package + // that we just installed. + if (uninstall) { + mDeleteObserver.reset(); + mPackageManager.deletePackage(mInstallObserver.mPackageName, + mDeleteObserver, 0); + mDeleteObserver.waitForCompletion(); + } } } catch (IOException e) { Slog.e(TAG, "Unable to transcribe restored apk for install"); @@ -2441,38 +2528,48 @@ class BackupManagerService extends IBackupManager.Stub { boolean hasApk = str[0].equals("1"); offset = extractLine(buffer, offset, str); int numSigs = Integer.parseInt(str[0]); - Signature[] sigs = null; if (numSigs > 0) { - sigs = new Signature[numSigs]; + Signature[] sigs = new Signature[numSigs]; for (int i = 0; i < numSigs; i++) { offset = extractLine(buffer, offset, str); sigs[i] = new Signature(str[0]); } + mManifestSignatures.put(info.packageName, sigs); // Okay, got the manifest info we need... try { - // Verify signatures against any installed version; if they - // don't match, then we fall though and ignore the data. The - // signatureMatch() method explicitly ignores the signature - // check for packages installed on the system partition, because - // such packages are signed with the platform cert instead of - // the app developer's cert, so they're different on every - // device. PackageInfo pkgInfo = mPackageManager.getPackageInfo( info.packageName, PackageManager.GET_SIGNATURES); - if (signaturesMatch(sigs, pkgInfo)) { - if (pkgInfo.versionCode >= version) { - Slog.i(TAG, "Sig + version match; taking data"); - policy = RestorePolicy.ACCEPT; + // Fall through to IGNORE if the app explicitly disallows backup + final int flags = pkgInfo.applicationInfo.flags; + if ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) { + // Verify signatures against any installed version; if they + // don't match, then we fall though and ignore the data. The + // signatureMatch() method explicitly ignores the signature + // check for packages installed on the system partition, because + // such packages are signed with the platform cert instead of + // the app developer's cert, so they're different on every + // device. + if (signaturesMatch(sigs, pkgInfo)) { + if (pkgInfo.versionCode >= version) { + Slog.i(TAG, "Sig + version match; taking data"); + policy = RestorePolicy.ACCEPT; + } else { + // The data is from a newer version of the app than + // is presently installed. That means we can only + // use it if the matching apk is also supplied. + Slog.d(TAG, "Data version " + version + + " is newer than installed version " + + pkgInfo.versionCode + " - requiring apk"); + policy = RestorePolicy.ACCEPT_IF_APK; + } } else { - // The data is from a newer version of the app than - // is presently installed. That means we can only - // use it if the matching apk is also supplied. - Slog.d(TAG, "Data version " + version - + " is newer than installed version " - + pkgInfo.versionCode + " - requiring apk"); - policy = RestorePolicy.ACCEPT_IF_APK; + Slog.w(TAG, "Restore manifest signatures do not match " + + "installed application for " + info.packageName); } + } else { + if (DEBUG) Slog.i(TAG, "Restore manifest from " + + info.packageName + " but allowBackup=false"); } } catch (NameNotFoundException e) { // Okay, the target app isn't installed. We can process diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 7801aec..fba293c 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -259,7 +259,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub unbindAllServicesLocked(); } updateClientsLocked(); - updateInputFilterLocked(); } } }); @@ -319,6 +318,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType) { List<AccessibilityServiceInfo> result = mEnabledServicesForFeedbackTempList; + result.clear(); List<Service> services = mServices; synchronized (mLock) { while (feedbackType != 0) { @@ -327,7 +327,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final int serviceCount = services.size(); for (int i = 0; i < serviceCount; i++) { Service service = services.get(i); - if (service.mFeedbackType == feedbackType) { + if ((service.mFeedbackType & feedbackTypeBit) != 0) { result.add(service.mAccessibilityServiceInfo); } } @@ -368,10 +368,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub service.setAccessibilityServiceInfo(oldInfo); } else { service.setAccessibilityServiceInfo(info); - tryAddServiceLocked(service); } - - updateInputFilterLocked(); } return; default: @@ -772,6 +769,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } mNotificationTimeout = info.notificationTimeout; mIsDefault = (info.flags & AccessibilityServiceInfo.DEFAULT) != 0; + + synchronized (mLock) { + tryAddServiceLocked(this); + } } /** @@ -794,7 +795,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub */ public boolean unbind() { if (mService != null) { - tryRemoveServiceLocked(this); + synchronized (mLock) { + tryRemoveServiceLocked(this); + } mContext.unbindService(this); mService = null; return true; @@ -809,7 +812,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub * @return True if the service is configured, false otherwise. */ public boolean isConfigured() { - return (mEventTypes != 0 && mFeedbackType != 0); + return (mEventTypes != 0 && mFeedbackType != 0 && mService != null); } public void setServiceInfo(AccessibilityServiceInfo info) { diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index e8155b4..7ea0591 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -1212,8 +1212,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return null; } - for (String iface : ifaces) { - for (String regex : mUpstreamIfaceRegexs) { + for (String regex : mUpstreamIfaceRegexs) { + for (String iface : ifaces) { if (iface.matches(regex)) { // verify it is active InterfaceConfiguration ifcg = null; |
