summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2013-08-06 00:16:04 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-08-06 00:16:04 +0000
commit03901667db75696ccd544809e0e7bc000a99f417 (patch)
tree7d62b241f4dbc6301544d7820f526b621085cdaf /core/java/android
parent254798f22f133338d016977c65c06e5f3c8dd033 (diff)
parent221ea892dcc661bd07d6f36ff012edca2c48aed4 (diff)
downloadframeworks_base-03901667db75696ccd544809e0e7bc000a99f417.zip
frameworks_base-03901667db75696ccd544809e0e7bc000a99f417.tar.gz
frameworks_base-03901667db75696ccd544809e0e7bc000a99f417.tar.bz2
Merge "Start restricting service calls with implicit intents."
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/ContextImpl.java24
-rw-r--r--core/java/android/bluetooth/BluetoothA2dp.java17
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java17
-rw-r--r--core/java/android/bluetooth/BluetoothHealth.java17
-rw-r--r--core/java/android/bluetooth/BluetoothInputDevice.java18
-rw-r--r--core/java/android/bluetooth/BluetoothPan.java25
-rw-r--r--core/java/android/bluetooth/BluetoothPbap.java19
-rw-r--r--core/java/android/content/Context.java26
-rw-r--r--core/java/android/content/Intent.java37
-rw-r--r--core/java/android/os/Build.java8
10 files changed, 156 insertions, 52 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index ab11903..60c0288 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1444,6 +1444,14 @@ class ContextImpl extends Context {
@Override
public ComponentName startServiceAsUser(Intent service, UserHandle user) {
try {
+ if (service.getComponent() == null && service.getPackage() == null) {
+ if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KEY_LIME_PIE) {
+ IllegalArgumentException ex = new IllegalArgumentException(
+ "Service Intent must be explicit: " + service);
+ Log.wtf(TAG, "This will become an error", ex);
+ //throw ex;
+ }
+ }
service.prepareToLeaveProcess();
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
@@ -1468,6 +1476,14 @@ class ContextImpl extends Context {
@Override
public boolean stopServiceAsUser(Intent service, UserHandle user) {
try {
+ if (service.getComponent() == null && service.getPackage() == null) {
+ if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KEY_LIME_PIE) {
+ IllegalArgumentException ex = new IllegalArgumentException(
+ "Service Intent must be explicit: " + service);
+ Log.wtf(TAG, "This will become an error", ex);
+ //throw ex;
+ }
+ }
service.prepareToLeaveProcess();
int res = ActivityManagerNative.getDefault().stopService(
mMainThread.getApplicationThread(), service,
@@ -1503,6 +1519,14 @@ class ContextImpl extends Context {
} else {
throw new RuntimeException("Not supported in system context");
}
+ if (service.getComponent() == null && service.getPackage() == null) {
+ if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KEY_LIME_PIE) {
+ IllegalArgumentException ex = new IllegalArgumentException(
+ "Service Intent must be explicit: " + service);
+ Log.wtf(TAG, "This will become an error", ex);
+ //throw ex;
+ }
+ }
try {
IBinder token = getActivityToken();
if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 6fdf3b4..d7d8cdb 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -128,9 +128,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
- if (!mContext.bindService(new Intent(IBluetoothA2dp.class.getName()), mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth A2DP Service");
- }
+ doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
@@ -157,9 +155,18 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
}
- if (!context.bindService(new Intent(IBluetoothA2dp.class.getName()), mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth A2DP Service");
+ doBind();
+ }
+
+ boolean doBind() {
+ Intent intent = new Intent(IBluetoothA2dp.class.getName());
+ ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+ Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
+ return false;
}
+ return true;
}
/*package*/ void close() {
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 963e9fc..5a5764d 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -241,9 +241,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
- if (!mContext.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth Headset Service");
- }
+ doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
@@ -270,9 +268,18 @@ public final class BluetoothHeadset implements BluetoothProfile {
}
}
- if (!context.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth Headset Service");
+ doBind();
+ }
+
+ boolean doBind() {
+ Intent intent = new Intent(IBluetoothHeadset.class.getName());
+ ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+ Log.e(TAG, "Could not bind to Bluetooth Headset Service with " + intent);
+ return false;
}
+ return true;
}
/**
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index cb23662..b1a084a 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -117,9 +117,7 @@ public final class BluetoothHealth implements BluetoothProfile {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
- if (!mContext.bindService(new Intent(IBluetoothHealth.class.getName()), mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth Health Service");
- }
+ doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
@@ -483,9 +481,18 @@ public final class BluetoothHealth implements BluetoothProfile {
}
}
- if (!context.bindService(new Intent(IBluetoothHealth.class.getName()), mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth Health Service");
+ doBind();
+ }
+
+ boolean doBind() {
+ Intent intent = new Intent(IBluetoothHealth.class.getName());
+ ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+ Log.e(TAG, "Could not bind to Bluetooth Health Service with " + intent);
+ return false;
}
+ return true;
}
/*package*/ void close() {
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index db7e424..f9c789c 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -206,9 +206,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
- if (!mContext.bindService(new Intent(IBluetoothInputDevice.class.getName()), mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth HID Service");
- }
+ doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
@@ -237,10 +235,18 @@ public final class BluetoothInputDevice implements BluetoothProfile {
}
}
- if (!context.bindService(new Intent(IBluetoothInputDevice.class.getName()),
- mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth HID Service");
+ doBind();
+ }
+
+ boolean doBind() {
+ Intent intent = new Intent(IBluetoothInputDevice.class.getName());
+ ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+ Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent);
+ return false;
}
+ return true;
}
/*package*/ void close() {
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index e25ec86..83d4329 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -137,12 +137,20 @@ public final class BluetoothPan implements BluetoothProfile {
} catch (RemoteException re) {
Log.w(TAG,"Unable to register BluetoothStateChangeCallback",re);
}
- Log.d(TAG, "BluetoothPan() call bindService");
- if (!context.bindService(new Intent(IBluetoothPan.class.getName()),
- mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth HID Service");
+ if (VDBG) Log.d(TAG, "BluetoothPan() call bindService");
+ doBind();
+ if (VDBG) Log.d(TAG, "BluetoothPan(), bindService called");
+ }
+
+ boolean doBind() {
+ Intent intent = new Intent(IBluetoothPan.class.getName());
+ ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+ Log.e(TAG, "Could not bind to Bluetooth Pan Service with " + intent);
+ return false;
}
- Log.d(TAG, "BluetoothPan(), bindService called");
+ return true;
}
/*package*/ void close() {
@@ -170,11 +178,8 @@ public final class BluetoothPan implements BluetoothProfile {
//Handle enable request to bind again.
if (on) {
Log.d(TAG, "onBluetoothStateChange(on) call bindService");
- if (!mContext.bindService(new Intent(IBluetoothPan.class.getName()),
- mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth HID Service");
- }
- Log.d(TAG, "BluetoothPan(), bindService called");
+ doBind();
+ if (VDBG) Log.d(TAG, "BluetoothPan(), bindService called");
} else {
if (VDBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index b5280e5..c42251f 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -129,11 +129,7 @@ public class BluetoothPbap {
try {
if (mService == null) {
if (VDBG) Log.d(TAG,"Binding service...");
- if (!mContext.bindService(
- new Intent(IBluetoothPbap.class.getName()),
- mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth PBAP Service");
- }
+ doBind();
}
} catch (Exception re) {
Log.e(TAG,"",re);
@@ -158,9 +154,18 @@ public class BluetoothPbap {
Log.e(TAG,"",e);
}
}
- if (!context.bindService(new Intent(IBluetoothPbap.class.getName()), mConnection, 0)) {
- Log.e(TAG, "Could not bind to Bluetooth Pbap Service");
+ doBind();
+ }
+
+ boolean doBind() {
+ Intent intent = new Intent(IBluetoothPbap.class.getName());
+ ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+ Log.e(TAG, "Could not bind to Bluetooth Pbap Service with " + intent);
+ return false;
}
+ return true;
}
protected void finalize() throws Throwable {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 0b1127c..5c37206 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -976,7 +976,7 @@ public abstract class Context {
* May be null if there are no options. See {@link android.app.ActivityOptions}
* for how to build the Bundle supplied here; there are no supported definitions
* for building it manually.
- * @param user The UserHandle of the user to start this activity for.
+ * @param userId The UserHandle of the user to start this activity for.
* @throws ActivityNotFoundException &nbsp;
* @hide
*/
@@ -1573,9 +1573,11 @@ public abstract class Context {
/**
* Request that a given application service be started. The Intent
- * can either contain the complete class name of a specific service
- * implementation to start, or an abstract definition through the
- * action and other fields of the kind of service to start. If this service
+ * should contain either contain the complete class name of a specific service
+ * implementation to start or a specific package name to target. If the
+ * Intent is less specified, it will either throw an {@link IllegalArgumentException}
+ * (if the caller targets {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE} or later),
+ * or which of multiple matching services it finds and uses will be undefined. If this service
* is not already running, it will be instantiated and started (creating a
* process for it if needed); if it is running then it remains running.
*
@@ -1601,10 +1603,9 @@ public abstract class Context {
* <p>This function will throw {@link SecurityException} if you do not
* have permission to start the given service.
*
- * @param service Identifies the service to be started. The Intent may
- * specify either an explicit component name to start, or a logical
- * description (action, category, etc) to match an
- * {@link IntentFilter} published by a service. Additional values
+ * @param service Identifies the service to be started. The Intent must be either
+ * fully explicit (supplying a component name) or specify a specific package
+ * name it is targetted to. Additional values
* may be included in the Intent extras to supply arguments along with
* this specific start call.
*
@@ -1634,10 +1635,9 @@ public abstract class Context {
* <p>This function will throw {@link SecurityException} if you do not
* have permission to stop the given service.
*
- * @param service Description of the service to be stopped. The Intent may
- * specify either an explicit component name to start, or a logical
- * description (action, category, etc) to match an
- * {@link IntentFilter} published by a service.
+ * @param service Description of the service to be stopped. The Intent must be either
+ * fully explicit (supplying a component name) or specify a specific package
+ * name it is targetted to.
*
* @return If there is a service matching the given Intent that is already
* running, then it is stopped and {@code true} is returned; else {@code false} is returned.
@@ -2296,7 +2296,7 @@ public abstract class Context {
* camera devices.
*
* @see #getSystemService
- * @see android.hardware.camera.CameraManager
+ * @see android.hardware.camera2.CameraManager
*/
public static final String CAMERA_SERVICE = "camera";
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 30ea3f9..205ca6b 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -16,6 +16,7 @@
package android.content;
+import android.content.pm.ApplicationInfo;
import android.util.ArraySet;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -44,6 +45,7 @@ import java.io.Serializable;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
import java.util.Locale;
import java.util.Set;
@@ -5034,6 +5036,39 @@ public class Intent implements Parcelable, Cloneable {
}
/**
+ * Special function for use by the system to resolve service
+ * intents to system apps. Throws an exception if there are
+ * multiple potential matches to the Intent. Returns null if
+ * there are no matches.
+ * @hide
+ */
+ public ComponentName resolveSystemService(PackageManager pm, int flags) {
+ if (mComponent != null) {
+ return mComponent;
+ }
+
+ List<ResolveInfo> results = pm.queryIntentServices(this, flags);
+ if (results == null) {
+ return null;
+ }
+ ComponentName comp = null;
+ for (int i=0; i<results.size(); i++) {
+ ResolveInfo ri = results.get(i);
+ if ((ri.serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
+ continue;
+ }
+ ComponentName foundComp = new ComponentName(ri.serviceInfo.applicationInfo.packageName,
+ ri.serviceInfo.name);
+ if (comp != null) {
+ throw new IllegalStateException("Multiple system services handle " + this
+ + ": " + comp + ", " + foundComp);
+ }
+ comp = foundComp;
+ }
+ return comp;
+ }
+
+ /**
* Set the general action to be performed.
*
* @param action An action name, such as ACTION_VIEW. Application-specific
@@ -5068,7 +5103,7 @@ public class Intent implements Parcelable, Cloneable {
*
* @see #getData
* @see #setDataAndNormalize
- * @see android.net.Intent#normalize
+ * @see android.net.Uri#normalizeScheme()
*/
public Intent setData(Uri data) {
mData = data;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 71c3e4a..dd40e35 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -439,6 +439,14 @@ public class Build {
/**
* Android X.X: Key Lime Pie, another tasty treat.
+ *
+ * <p>Applications targeting this or a later release will get these
+ * new changes in behavior:</p>
+ * <ul>
+ * <li>It is no longer allowed to use implicit intents with
+ * {@link android.content.Context#startService} or
+ * {@link android.content.Context#bindService}.
+ * </ul>
*/
public static final int KEY_LIME_PIE = CUR_DEVELOPMENT;
}