Fix issue #10378741: configupdater needs to be explicit when it calls startService() Not enough time to fix everything, so instead we'll make it a warning in this release and finish up turning it into a target-SDK based exception in the next release. Change-Id: I5aae64a1225a145f03ba4162238b53d5e401aba2
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 300424c..0ad0a99 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java
@@ -1453,29 +1453,39 @@ } } + private void validateServiceIntent(Intent service) { + if (service.getComponent() == null && service.getPackage() == null) { + if (true || getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) { + Log.w(TAG, "Implicit intents with startService are not safe: " + service + + " " + Debug.getCallers(2, 3)); + //IllegalArgumentException ex = new IllegalArgumentException( + // "Service Intent must be explicit: " + service); + //Log.e(TAG, "This will become an error", ex); + //throw ex; + } + } + } + @Override public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); - return startServiceAsUser(service, mUser); + return startServiceCommon(service, mUser); } @Override public boolean stopService(Intent service) { warnIfCallingFromSystemProcess(); - return stopServiceAsUser(service, mUser); + return stopServiceCommon(service, mUser); } @Override public ComponentName startServiceAsUser(Intent service, UserHandle user) { + return startServiceCommon(service, user); + } + + private ComponentName startServiceCommon(Intent service, UserHandle user) { try { - if (service.getComponent() == null && service.getPackage() == null) { - if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) { - IllegalArgumentException ex = new IllegalArgumentException( - "Service Intent must be explicit: " + service); - Log.e(TAG, "This will become an error", ex); - //throw ex; - } - } + validateServiceIntent(service); service.prepareToLeaveProcess(); ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, @@ -1499,15 +1509,12 @@ @Override public boolean stopServiceAsUser(Intent service, UserHandle user) { + return stopServiceCommon(service, user); + } + + private boolean stopServiceCommon(Intent service, UserHandle user) { try { - if (service.getComponent() == null && service.getPackage() == null) { - if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) { - IllegalArgumentException ex = new IllegalArgumentException( - "Service Intent must be explicit: " + service); - Log.e(TAG, "This will become an error", ex); - //throw ex; - } - } + validateServiceIntent(service); service.prepareToLeaveProcess(); int res = ActivityManagerNative.getDefault().stopService( mMainThread.getApplicationThread(), service, @@ -1526,13 +1533,18 @@ public boolean bindService(Intent service, ServiceConnection conn, int flags) { warnIfCallingFromSystemProcess(); - return bindServiceAsUser(service, conn, flags, Process.myUserHandle()); + return bindServiceCommon(service, conn, flags, Process.myUserHandle()); } /** @hide */ @Override public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, UserHandle user) { + return bindServiceCommon(service, conn, flags, user); + } + + private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, + UserHandle user) { IServiceConnection sd; if (conn == null) { throw new IllegalArgumentException("connection is null"); @@ -1543,14 +1555,7 @@ } else { throw new RuntimeException("Not supported in system context"); } - if (service.getComponent() == null && service.getPackage() == null) { - if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) { - IllegalArgumentException ex = new IllegalArgumentException( - "Service Intent must be explicit: " + service); - Log.e(TAG, "This will become an error", ex); - //throw ex; - } - } + validateServiceIntent(service); try { IBinder token = getActivityToken(); if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index ea9fd06..2e3b81d 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java
@@ -1582,6 +1582,22 @@ } /** + * Return a string consisting of methods and locations at multiple call stack levels. + * @param depth the number of levels to return, starting with the immediate caller. + * @return a string describing the call stack. + * {@hide} + */ + public static String getCallers(final int start, int depth) { + final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); + StringBuffer sb = new StringBuffer(); + depth += start; + for (int i = start; i < depth; i++) { + sb.append(getCaller(callStack, i)).append(" "); + } + return sb.toString(); + } + + /** * Like {@link #getCallers(int)}, but each location is append to the string * as a new line with <var>linePrefix</var> in front of it. * @param depth the number of levels to return, starting with the immediate caller.