summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Pundir <amit.pundir@linaro.org>2013-09-12 01:41:54 +0530
committerAmit Pundir <amit.pundir@linaro.org>2013-09-12 01:41:54 +0530
commit24e70286545561e19d60f250dffff304eda74686 (patch)
tree70f2e7089ddd52d63ae2a8c5b421c52757900ab0
parent161d8a6ad7edcfda770feca26c572da6d2ad8ff2 (diff)
parent36ebb70df6f2e7c62adc9bd8372293a2194d6516 (diff)
downloadbase-24e70286545561e19d60f250dffff304eda74686.tar.gz
Merge android-4.3_r2.2:
Android 4.3 release 2.2 # gpg: directory `/home/pundiramit/.gnupg' created # gpg: new configuration file `/home/pundiramit/.gnupg/gpg.conf' created # gpg: WARNING: options in `/home/pundiramit/.gnupg/gpg.conf' are not yet active during this run # gpg: keyring `/home/pundiramit/.gnupg/pubring.gpg' created # gpg: Signature made Wednesday 21 August 2013 03:35:49 AM IST using DSA key ID 9AB10E78 # gpg: Can't check signature: public key not found * tag 'android-4.3_r2.2': Use hostname verifier directly instead of instance DO NOT MERGE Fix issue #10226007: Reset apps restores most of the changed settings... Add new app ops method to reset all op modes. Revert "Add version identifier to app ops." Add version identifier to app ops. Allow the user to block notifications for foreground services. (DO NOT MERGE) Fix pub issue #58043: Copy crash in Android 4.3...
-rw-r--r--core/java/android/app/ActivityManager.java5
-rw-r--r--core/java/android/app/AppOpsManager.java8
-rw-r--r--core/java/android/net/SSLCertificateSocketFactory.java5
-rw-r--r--core/java/com/android/internal/app/IAppOpsService.aidl1
-rw-r--r--services/java/com/android/server/AppOpsService.java112
-rw-r--r--services/java/com/android/server/ClipboardService.java35
-rw-r--r--services/java/com/android/server/NotificationManagerService.java12
7 files changed, 138 insertions, 40 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 443cb65ff36a..944da9eb6f9c 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -16,6 +16,7 @@
package android.app;
+import android.R;
import com.android.internal.app.IUsageStats;
import com.android.internal.os.PkgUsageStats;
import com.android.internal.util.MemInfoReader;
@@ -369,9 +370,9 @@ public class ActivityManager {
// Really brain dead right now -- just take this from the configured
// vm heap size, and assume it is in megabytes and thus ends with "m".
String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m");
- return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+ return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length() - 1));
}
-
+
/**
* Used by persistent processes to determine if they are running on a
* higher-end device so should be okay using hardware drawing acceleration
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index c9776f17fc9a..4fcb18a84b4f 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -422,6 +422,14 @@ public class AppOpsManager {
}
}
+ /** @hide */
+ public void resetAllModes() {
+ try {
+ mService.resetAllModes();
+ } catch (RemoteException e) {
+ }
+ }
+
public void startWatchingMode(int op, String packageName, final Callback callback) {
synchronized (mModeWatchers) {
IAppOpsCallback cb = mModeWatchers.get(callback);
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index 2a2f7cf81f84..0fe5cc415c6a 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -81,9 +81,6 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
}
};
- private static final HostnameVerifier HOSTNAME_VERIFIER =
- HttpsURLConnection.getDefaultHostnameVerifier();
-
private SSLSocketFactory mInsecureFactory = null;
private SSLSocketFactory mSecureFactory = null;
private TrustManager[] mTrustManagers = null;
@@ -195,7 +192,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
if (session == null) {
throw new SSLException("Cannot verify SSL socket without session");
}
- if (!HOSTNAME_VERIFIER.verify(hostname, session)) {
+ if (!HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session)) {
throw new SSLPeerUnverifiedException("Cannot verify hostname: " + hostname);
}
}
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index a9da86376153..cfd9cc7cb071 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -33,4 +33,5 @@ interface IAppOpsService {
List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
void setMode(int code, int uid, String packageName, int mode);
+ void resetAllModes();
}
diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java
index a402642bc0de..a55fddcd7ed8 100644
--- a/services/java/com/android/server/AppOpsService.java
+++ b/services/java/com/android/server/AppOpsService.java
@@ -27,6 +27,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import android.app.AppOpsManager;
import android.content.Context;
@@ -42,6 +43,7 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.util.AtomicFile;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
@@ -288,6 +290,24 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
+ private void pruneOp(Op op, int uid, String packageName) {
+ if (op.time == 0 && op.rejectTime == 0) {
+ Ops ops = getOpsLocked(uid, packageName, false);
+ if (ops != null) {
+ ops.remove(op.op);
+ if (ops.size() <= 0) {
+ HashMap<String, Ops> pkgOps = mUidOps.get(uid);
+ if (pkgOps != null) {
+ pkgOps.remove(ops.packageName);
+ if (pkgOps.size() <= 0) {
+ mUidOps.remove(uid);
+ }
+ }
+ }
+ }
+ }
+ }
+
@Override
public void setMode(int code, int uid, String packageName, int mode) {
verifyIncomingUid(uid);
@@ -316,21 +336,7 @@ public class AppOpsService extends IAppOpsService.Stub {
if (mode == AppOpsManager.MODE_ALLOWED) {
// If going into the default mode, prune this op
// if there is nothing else interesting in it.
- if (op.time == 0 && op.rejectTime == 0) {
- Ops ops = getOpsLocked(uid, packageName, false);
- if (ops != null) {
- ops.remove(op.op);
- if (ops.size() <= 0) {
- HashMap<String, Ops> pkgOps = mUidOps.get(uid);
- if (pkgOps != null) {
- pkgOps.remove(ops.packageName);
- if (pkgOps.size() <= 0) {
- mUidOps.remove(uid);
- }
- }
- }
- }
- }
+ pruneOp(op, uid, packageName);
}
scheduleWriteNowLocked();
}
@@ -346,6 +352,82 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
+ private static HashMap<Callback, ArrayList<Pair<String, Integer>>> addCallbacks(
+ HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks,
+ String packageName, int op, ArrayList<Callback> cbs) {
+ if (cbs == null) {
+ return callbacks;
+ }
+ if (callbacks == null) {
+ callbacks = new HashMap<Callback, ArrayList<Pair<String, Integer>>>();
+ }
+ for (int i=0; i<cbs.size(); i++) {
+ Callback cb = cbs.get(i);
+ ArrayList<Pair<String, Integer>> reports = callbacks.get(cb);
+ if (reports == null) {
+ reports = new ArrayList<Pair<String, Integer>>();
+ callbacks.put(cb, reports);
+ }
+ reports.add(new Pair<String, Integer>(packageName, op));
+ }
+ return callbacks;
+ }
+
+ @Override
+ public void resetAllModes() {
+ mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
+ Binder.getCallingPid(), Binder.getCallingUid(), null);
+ HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks = null;
+ synchronized (this) {
+ boolean changed = false;
+ for (int i=mUidOps.size()-1; i>=0; i--) {
+ HashMap<String, Ops> packages = mUidOps.valueAt(i);
+ Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, Ops> ent = it.next();
+ String packageName = ent.getKey();
+ Ops pkgOps = ent.getValue();
+ for (int j=pkgOps.size()-1; j>=0; j--) {
+ Op curOp = pkgOps.valueAt(j);
+ if (curOp.mode != AppOpsManager.MODE_ALLOWED) {
+ curOp.mode = AppOpsManager.MODE_ALLOWED;
+ changed = true;
+ callbacks = addCallbacks(callbacks, packageName, curOp.op,
+ mOpModeWatchers.get(curOp.op));
+ callbacks = addCallbacks(callbacks, packageName, curOp.op,
+ mPackageModeWatchers.get(packageName));
+ if (curOp.time == 0 && curOp.rejectTime == 0) {
+ pkgOps.removeAt(j);
+ }
+ }
+ }
+ if (pkgOps.size() == 0) {
+ it.remove();
+ }
+ }
+ if (packages.size() == 0) {
+ mUidOps.removeAt(i);
+ }
+ }
+ if (changed) {
+ scheduleWriteNowLocked();
+ }
+ }
+ if (callbacks != null) {
+ for (Map.Entry<Callback, ArrayList<Pair<String, Integer>>> ent : callbacks.entrySet()) {
+ Callback cb = ent.getKey();
+ ArrayList<Pair<String, Integer>> reports = ent.getValue();
+ for (int i=0; i<reports.size(); i++) {
+ Pair<String, Integer> rep = reports.get(i);
+ try {
+ cb.mCallback.opChanged(rep.second, rep.first);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+ }
+
@Override
public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) {
synchronized (this) {
diff --git a/services/java/com/android/server/ClipboardService.java b/services/java/com/android/server/ClipboardService.java
index 058857ddb605..0bf03b5ff453 100644
--- a/services/java/com/android/server/ClipboardService.java
+++ b/services/java/com/android/server/ClipboardService.java
@@ -154,31 +154,36 @@ public class ClipboardService extends IClipboard.Stub {
if (clip != null && clip.getItemCount() <= 0) {
throw new IllegalArgumentException("No items");
}
- if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, Binder.getCallingUid(),
+ final int callingUid = Binder.getCallingUid();
+ if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, callingUid,
callingPackage) != AppOpsManager.MODE_ALLOWED) {
return;
}
- checkDataOwnerLocked(clip, Binder.getCallingUid());
+ checkDataOwnerLocked(clip, callingUid);
clearActiveOwnersLocked();
PerUserClipboard clipboard = getClipboard();
clipboard.primaryClip = clip;
+ final long ident = Binder.clearCallingIdentity();
final int n = clipboard.primaryClipListeners.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- ListenerInfo li = (ListenerInfo)
- clipboard.primaryClipListeners.getBroadcastCookie(i);
- if (mAppOps.checkOpNoThrow(AppOpsManager.OP_READ_CLIPBOARD, li.mUid,
- li.mPackageName) == AppOpsManager.MODE_ALLOWED) {
- clipboard.primaryClipListeners.getBroadcastItem(i)
- .dispatchPrimaryClipChanged();
+ try {
+ for (int i = 0; i < n; i++) {
+ try {
+ ListenerInfo li = (ListenerInfo)
+ clipboard.primaryClipListeners.getBroadcastCookie(i);
+ if (mAppOps.checkOpNoThrow(AppOpsManager.OP_READ_CLIPBOARD, li.mUid,
+ li.mPackageName) == AppOpsManager.MODE_ALLOWED) {
+ clipboard.primaryClipListeners.getBroadcastItem(i)
+ .dispatchPrimaryClipChanged();
+ }
+ } catch (RemoteException e) {
+ // The RemoteCallbackList will take care of removing
+ // the dead object for us.
}
- } catch (RemoteException e) {
-
- // The RemoteCallbackList will take care of removing
- // the dead object for us.
}
+ } finally {
+ clipboard.primaryClipListeners.finishBroadcast();
+ Binder.restoreCallingIdentity(ident);
}
- clipboard.primaryClipListeners.finishBroadcast();
}
}
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 29aaeaf33f4f..29780c06e8e5 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -1606,7 +1606,7 @@ public class NotificationManagerService extends INotificationManager.Stub
Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification);
}
checkCallerIsSystemOrSameApp(pkg);
- final boolean isSystemNotification = isCallerSystem() || ("android".equals(pkg));
+ final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg));
userId = ActivityManager.handleIncomingUser(callingPid,
callingUid, userId, true, false, "enqueueNotification", pkg);
@@ -2084,14 +2084,18 @@ public class NotificationManagerService extends INotificationManager.Stub
cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId);
}
- // Return true if the caller is a system or phone UID and therefore should not have
+ // Return true if the UID is a system or phone UID and therefore should not have
// any notifications or toasts blocked.
- boolean isCallerSystem() {
- final int uid = Binder.getCallingUid();
+ boolean isUidSystem(int uid) {
final int appid = UserHandle.getAppId(uid);
return (appid == Process.SYSTEM_UID || appid == Process.PHONE_UID || uid == 0);
}
+ // same as isUidSystem(int, int) for the Binder caller's UID.
+ boolean isCallerSystem() {
+ return isUidSystem(Binder.getCallingUid());
+ }
+
void checkCallerIsSystem() {
if (isCallerSystem()) {
return;