summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server')
-rw-r--r--services/java/com/android/server/BackupManagerService.java139
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java17
-rw-r--r--services/java/com/android/server/connectivity/Tethering.java4
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;