diff options
| -rw-r--r-- | core/api/current.txt | 17 | ||||
| -rw-r--r-- | core/java/android/app/BackgroundServiceStartNotAllowedException.java | 62 | ||||
| -rw-r--r-- | core/java/android/app/ContextImpl.java | 2 | ||||
| -rw-r--r-- | core/java/android/app/ForegroundServiceStartNotAllowedException.java | 62 | ||||
| -rw-r--r-- | core/java/android/app/Service.java | 9 | ||||
| -rw-r--r-- | core/java/android/app/ServiceStartNotAllowedException.java | 43 | ||||
| -rw-r--r-- | core/java/android/content/Context.java | 17 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActiveServices.java | 5 | 
8 files changed, 210 insertions, 7 deletions
| diff --git a/core/api/current.txt b/core/api/current.txt index 8c56c5f55bdb..5b639ff0b00f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -4735,6 +4735,13 @@ package android.app {      field @NonNull public static final android.os.Parcelable.Creator<android.app.AutomaticZenRule> CREATOR;    } +  public final class BackgroundServiceStartNotAllowedException extends android.app.ServiceStartNotAllowedException implements android.os.Parcelable { +    ctor public BackgroundServiceStartNotAllowedException(@NonNull String); +    method public int describeContents(); +    method public void writeToParcel(@NonNull android.os.Parcel, int); +    field @NonNull public static final android.os.Parcelable.Creator<android.app.BackgroundServiceStartNotAllowedException> CREATOR; +  } +    public class DatePickerDialog extends android.app.AlertDialog implements android.widget.DatePicker.OnDateChangedListener android.content.DialogInterface.OnClickListener {      ctor public DatePickerDialog(@NonNull android.content.Context);      ctor public DatePickerDialog(@NonNull android.content.Context, @StyleRes int); @@ -4980,6 +4987,13 @@ package android.app {      method @Deprecated public void setSelectedGroup(int);    } +  public final class ForegroundServiceStartNotAllowedException extends android.app.ServiceStartNotAllowedException implements android.os.Parcelable { +    ctor public ForegroundServiceStartNotAllowedException(@NonNull String); +    method public int describeContents(); +    method public void writeToParcel(@NonNull android.os.Parcel, int); +    field @NonNull public static final android.os.Parcelable.Creator<android.app.ForegroundServiceStartNotAllowedException> CREATOR; +  } +    @Deprecated public class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener {      ctor @Deprecated public Fragment();      method @Deprecated public void dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]); @@ -6563,6 +6577,9 @@ package android.app {      field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1    } +  public abstract class ServiceStartNotAllowedException extends java.lang.IllegalStateException { +  } +    public abstract class SharedElementCallback {      ctor public SharedElementCallback();      method public android.os.Parcelable onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF); diff --git a/core/java/android/app/BackgroundServiceStartNotAllowedException.java b/core/java/android/app/BackgroundServiceStartNotAllowedException.java new file mode 100644 index 000000000000..f6361b52bf9d --- /dev/null +++ b/core/java/android/app/BackgroundServiceStartNotAllowedException.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.app; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Exception thrown when an app tries to start a background {@link Service} when it's not allowed to + * do so. + */ +public final class BackgroundServiceStartNotAllowedException +        extends ServiceStartNotAllowedException implements Parcelable { +    /** +     * Constructor. +     */ +    public BackgroundServiceStartNotAllowedException(@NonNull String message) { +        super(message); +    } + +    BackgroundServiceStartNotAllowedException(@NonNull Parcel source) { +        super(source.readString()); +    } + +    @Override +    public int describeContents() { +        return 0; +    } + +    @Override +    public void writeToParcel(@NonNull Parcel dest, int flags) { +        dest.writeString(getMessage()); +    } + +    public static final @NonNull Creator<android.app.BackgroundServiceStartNotAllowedException> +            CREATOR = new Creator<android.app.BackgroundServiceStartNotAllowedException>() { +                @NonNull +                public android.app.BackgroundServiceStartNotAllowedException createFromParcel( +                        Parcel source) { +                    return new android.app.BackgroundServiceStartNotAllowedException(source); +                } + +                @NonNull +                public android.app.BackgroundServiceStartNotAllowedException[] newArray(int size) { +                    return new android.app.BackgroundServiceStartNotAllowedException[size]; +                } +            }; +} diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 85fb543a3967..bc798136f2e3 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1796,7 +1796,7 @@ class ContextImpl extends Context {                              "Unable to start service " + service                              + ": " + cn.getClassName());                  } else if (cn.getPackageName().equals("?")) { -                    throw new IllegalStateException( +                    throw ServiceStartNotAllowedException.newInstance(requireForeground,                              "Not allowed to start service " + service + ": " + cn.getClassName());                  }              } diff --git a/core/java/android/app/ForegroundServiceStartNotAllowedException.java b/core/java/android/app/ForegroundServiceStartNotAllowedException.java new file mode 100644 index 000000000000..41eeada2df6b --- /dev/null +++ b/core/java/android/app/ForegroundServiceStartNotAllowedException.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.app; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Exception thrown when an app tries to start a foreground {@link Service} when it's not allowed to + * do so. + */ +public final class ForegroundServiceStartNotAllowedException +        extends ServiceStartNotAllowedException implements Parcelable { +    /** +     * Constructor. +     */ +    public ForegroundServiceStartNotAllowedException(@NonNull String message) { +        super(message); +    } + +    ForegroundServiceStartNotAllowedException(@NonNull Parcel source) { +        super(source.readString()); +    } + +    @Override +    public int describeContents() { +        return 0; +    } + +    @Override +    public void writeToParcel(@NonNull Parcel dest, int flags) { +        dest.writeString(getMessage()); +    } + +    public static final @NonNull Creator<android.app.ForegroundServiceStartNotAllowedException> +            CREATOR = new Creator<android.app.ForegroundServiceStartNotAllowedException>() { +                @NonNull +                public android.app.ForegroundServiceStartNotAllowedException createFromParcel( +                        Parcel source) { +                    return new android.app.ForegroundServiceStartNotAllowedException(source); +                } + +                @NonNull +                public android.app.ForegroundServiceStartNotAllowedException[] newArray(int size) { +                    return new android.app.ForegroundServiceStartNotAllowedException[size]; +                } +            }; +} diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java index 3798de921dc7..2ceea7f1a6a8 100644 --- a/core/java/android/app/Service.java +++ b/core/java/android/app/Service.java @@ -697,7 +697,8 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac       * service element of manifest file. The value of attribute       * {@link android.R.attr#foregroundServiceType} can be multiple flags ORed together.</p>       * -     * @throws IllegalStateException If the app targeting API is +     * @throws ForegroundServiceStartNotAllowedException +     * If the app targeting API is       * {@link android.os.Build.VERSION_CODES#S} or later, and the service is restricted from       * becoming foreground service due to background restriction.       * @@ -738,8 +739,14 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac     * @param notification The Notification to be displayed.     * @param foregroundServiceType must be a subset flags of manifest attribute     * {@link android.R.attr#foregroundServiceType} flags. +   *     * @throws IllegalArgumentException if param foregroundServiceType is not subset of manifest     *     attribute {@link android.R.attr#foregroundServiceType}. +   * @throws ForegroundServiceStartNotAllowedException +   * If the app targeting API is +   * {@link android.os.Build.VERSION_CODES#S} or later, and the service is restricted from +   * becoming foreground service due to background restriction. +   *     * @see android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST     */      public final void startForeground(int id, @NonNull Notification notification, diff --git a/core/java/android/app/ServiceStartNotAllowedException.java b/core/java/android/app/ServiceStartNotAllowedException.java new file mode 100644 index 000000000000..33285b2190eb --- /dev/null +++ b/core/java/android/app/ServiceStartNotAllowedException.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.annotation.NonNull; + +/** + * Exception thrown when an app tries to start a {@link Service} when it's not allowed to do so. + */ +public abstract class ServiceStartNotAllowedException extends IllegalStateException { +    ServiceStartNotAllowedException(@NonNull String message) { +        super(message); +    } + +    /** +     * Return either {@link ForegroundServiceStartNotAllowedException} or +     * {@link BackgroundServiceStartNotAllowedException} +     * @hide +     */ +    @NonNull +    public static ServiceStartNotAllowedException newInstance(boolean foreground, +            @NonNull String message) { +        if (foreground) { +            return new ForegroundServiceStartNotAllowedException(message); +        } else { +            return new BackgroundServiceStartNotAllowedException(message); +        } +    } +} diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 4284dc2117c5..e20f706c2c35 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3118,8 +3118,18 @@ public abstract class Context {       *       * @throws SecurityException If the caller does not have permission to access the service       * or the service can not be found. -     * @throws IllegalStateException If the application is in a state where the service -     * can not be started (such as not in the foreground in a state when services are allowed). +     * @throws IllegalStateException +     * Before Android {@link android.os.Build.VERSION_CODES#S}, +     * if the application is in a state where the service +     * can not be started (such as not in the foreground in a state when services are allowed), +     * {@link IllegalStateException} was thrown. +     * @throws android.app.BackgroundServiceStartNotAllowedException +     * On Android {@link android.os.Build.VERSION_CODES#S} and later, +     * if the application is in a state where the service +     * can not be started (such as not in the foreground in a state when services are allowed), +     * {@link android.app.BackgroundServiceStartNotAllowedException} is thrown +     * This excemption extends {@link IllegalStateException}, so apps can +     * use {@code catch (IllegalStateException)} to catch both.       *       * @see #stopService       * @see #bindService @@ -3150,7 +3160,8 @@ public abstract class Context {       * @throws SecurityException If the caller does not have permission to access the service       * or the service can not be found.       * -     * @throws IllegalStateException If the caller app's targeting API is +     * @throws android.app.ForegroundServiceStartNotAllowedException +     * If the caller app's targeting API is       * {@link android.os.Build.VERSION_CODES#S} or later, and the foreground service is restricted       * from start due to background restriction.       * diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 5550999b2405..2efc83c4af06 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -52,6 +52,7 @@ import android.app.ActivityThread;  import android.app.AppGlobals;  import android.app.AppOpsManager;  import android.app.BroadcastOptions; +import android.app.ForegroundServiceStartNotAllowedException;  import android.app.IApplicationThread;  import android.app.IServiceConnection;  import android.app.Notification; @@ -693,7 +694,7 @@ public final class ActiveServices {                              + "could not resolve client package " + callingPackage);                  }                  if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, aInfo.uid)) { -                    throw new IllegalStateException(msg); +                    throw new ForegroundServiceStartNotAllowedException(msg);                  }                  return null;              } @@ -1778,7 +1779,7 @@ public final class ActiveServices {                          ignoreForeground = true;                          if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID,                                  r.appInfo.uid)) { -                            throw new IllegalStateException(msg); +                            throw new ForegroundServiceStartNotAllowedException(msg);                          }                      }                  } |