Loading core/api/current.txt +21 −0 Original line number Diff line number Diff line Loading @@ -27364,6 +27364,25 @@ package android.media.midi { package android.media.projection { @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public abstract class AppContentProjectionService extends android.app.Service { ctor public AppContentProjectionService(); method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent); method public abstract void onContentRequest(@NonNull android.media.projection.AppContentRequest); method public abstract void onContentRequestCanceled(); method public abstract boolean onLoopbackProjectionStarted(@NonNull android.media.projection.AppContentProjectionSession, int); method public abstract void onSessionStopped(@NonNull android.media.projection.AppContentProjectionSession); field public static final String SERVICE_INTERFACE = "android.media.projection.AppContentProjectionService"; } @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public class AppContentProjectionSession { method public void notifySessionStop(); } @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public final class AppContentRequest { method @NonNull public android.util.Size getThumbnailSize(); method public void provideContent(@NonNull java.util.List<android.media.projection.MediaProjectionAppContent>); } public final class MediaProjection { method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, int, @Nullable android.view.Surface, @Nullable android.hardware.display.VirtualDisplay.Callback, @Nullable android.os.Handler); method public void registerCallback(@NonNull android.media.projection.MediaProjection.Callback, @Nullable android.os.Handler); Loading Loading @@ -27392,6 +27411,7 @@ package android.media.projection { method @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public int getInitiallySelectedSource(); method @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public int getProjectionSources(); method @FlaggedApi("com.android.media.projection.flags.app_content_sharing") @Nullable public CharSequence getRequesterHint(); method @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public boolean isOwnAppContentProvided(); method @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public boolean isSourceEnabled(int); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.media.projection.MediaProjectionConfig> CREATOR; Loading @@ -27404,6 +27424,7 @@ package android.media.projection { ctor public MediaProjectionConfig.Builder(); method @NonNull public android.media.projection.MediaProjectionConfig build(); method @NonNull public android.media.projection.MediaProjectionConfig.Builder setInitiallySelectedSource(int); method @NonNull public android.media.projection.MediaProjectionConfig.Builder setOwnAppContentProvided(@NonNull android.content.Context, boolean); method @NonNull public android.media.projection.MediaProjectionConfig.Builder setRequesterHint(@Nullable String); method @NonNull public android.media.projection.MediaProjectionConfig.Builder setSourceEnabled(int, boolean); } media/java/android/media/projection/AppContentProjectionService.java 0 → 100644 +203 −0 Original line number Diff line number Diff line /* * Copyright 2025 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.media.projection; import android.annotation.EnforcePermission; import android.annotation.FlaggedApi; import android.annotation.SdkConstant; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.IBinder; import android.os.PermissionEnforcer; import android.os.RemoteCallback; import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.media.projection.flags.Flags; import java.util.List; /** * Service to be implemented by the application providing the {@link MediaProjectionAppContent}. * * <p> * To receive media projection callbacks related to app content sharing, this service must: * <ol> * <li> be declared with an intent-filter action * {@value AppContentProjectionService#SERVICE_INTERFACE} * <li> set {@code android:exported="true"} * <li> be protected by {@value android.Manifest.permission#MANAGE_MEDIA_PROJECTION} * <li> set * {@link MediaProjectionConfig.Builder#setOwnAppContentProvided(Context, boolean)} to * {@code true} * </ol> * <p> * <pre> * </application> * ... * <service * android:exported="true" * android:name="com.example.AppContentSharingService" * android:permission="android.permission.MANAGE_MEDIA_PROJECTION"> * <intent-filter> * <action android:name="android.media.projection.AppContentProjectionService"/> * </intent-filter> * </service> * </application> * </pre> * <p> * Only holders of {@value android.Manifest.permission#MANAGE_MEDIA_PROJECTION} are allowed to call * these callbacks. */ @FlaggedApi(Flags.FLAG_APP_CONTENT_SHARING) public abstract class AppContentProjectionService extends Service { /** * The {@link Intent} action that must be declared as handled by the service. * Put this in your manifest to reply to requests for app content projection. */ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) public static final String SERVICE_INTERFACE = "android.media.projection.AppContentProjectionService"; /** @hide **/ public static final String EXTRA_APP_CONTENT = "extra_app_content"; private AppContentProjectionCallbackInternal mService; private class AppContentProjectionCallbackInternal extends IAppContentProjectionCallback.Stub { private AppContentProjectionSession mSession; private AppContentProjectionCallbackInternal(PermissionEnforcer permissionEnforcer) { super(permissionEnforcer); } @Override @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) public void onContentRequest(RemoteCallback newContentConsumer, int width, int height) { onContentRequest_enforcePermission(); AppContentProjectionService.this.onContentRequest( new AppContentRequest(new Size(width, height), mediaProjectionAppContents -> { Bundle bundle = new Bundle(); bundle.putParcelableArray(EXTRA_APP_CONTENT, mediaProjectionAppContents); newContentConsumer.sendResult(bundle); })); } @Override @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) public void onLoopbackProjectionStarted(IAppContentProjectionSession session, int contentId) { onLoopbackProjectionStarted_enforcePermission(); if (mSession != null) { throw new IllegalStateException( "Only one single AppContentProjectionSession is supported"); } mSession = new AppContentProjectionSession(session); AppContentProjectionService.this.onLoopbackProjectionStarted( mSession, contentId ); } @Override @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) public void onSessionStopped() { onSessionStopped_enforcePermission(); AppContentProjectionService.this.onSessionStopped(mSession); mSession = null; } @Override @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) public void onContentRequestCanceled() { onContentRequestCanceled_enforcePermission(); AppContentProjectionService.this.onContentRequestCanceled(); } } @NonNull @Override public final IBinder onBind(@Nullable Intent intent) { if (mService == null) { mService = new AppContentProjectionCallbackInternal(new PermissionEnforcer(this)); } return mService; } /** * Called when the picker UI has been shown to the user. * <p> * App content should be returned by calling {@link AppContentRequest#provideContent(List)} * <p> * If the user picks one of the offered app content, * {@link #onLoopbackProjectionStarted(AppContentProjectionSession, int)} will be called with * the id corresponding to the chosen content. See {@link MediaProjectionAppContent} for more * information about the id. * @param request the request instance containing the characteristics of the content requested */ public abstract void onContentRequest(@NonNull AppContentRequest request); /** * Called when the user picked a content to be shared within the requesting app. * * <p>This can be called multiple times if the user picks a different content to * be shared at a later point. * * <p> {@code contentId} is the id that has been provided by this application during the * {@link #onContentRequest(AppContentRequest)} call. See * {@link MediaProjectionAppContent} for more information about the id. * * @param session the session started for sharing the selected {@link MediaProjectionAppContent} * @param contentId the id of the selected {@link MediaProjectionAppContent} * * @return {@code true} if the request has been fulfilled, {@code false} otherwise */ public abstract boolean onLoopbackProjectionStarted( @NonNull AppContentProjectionSession session, int contentId); /** * Called when the sharing session has been ended by the user or the system. The shared * resources can be discarded. * * <p> The provided session object is the same as the one provided when * {@link #onLoopbackProjectionStarted(AppContentProjectionSession, int)} was called. It can * be used to identify the session that is being terminated. * * <p> Note that if the session is terminated by this service by calling * {@link AppContentProjectionSession#notifySessionStop()}, this callback won't be called. * * @param session the same session object that was passed in * {@link #onLoopbackProjectionStarted(AppContentProjectionSession, int)} */ public abstract void onSessionStopped(@NonNull AppContentProjectionSession session); /** * Called when the user didn't pick some app content to be shared. This can happen if the * projection request was canceled, or the user picked another source (e.g. display, whole app). * <p> * Any resources created for sharing app content, such as thumbnails, can be discarded at this * point. */ public abstract void onContentRequestCanceled(); } media/java/android/media/projection/AppContentProjectionSession.java 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * Copyright 2025 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.media.projection; import android.annotation.FlaggedApi; import android.os.RemoteException; import com.android.media.projection.flags.Flags; /** * Represents a media projection session where the application receiving an instance of this class * is sharing its own content. * * <p> The application must use this class to notify if the sharing session terminates from its side * (e.g. the shared content is not available anymore). */ @FlaggedApi(Flags.FLAG_APP_CONTENT_SHARING) public class AppContentProjectionSession { private final IAppContentProjectionSession mSessionInternal; /** * @hide */ public AppContentProjectionSession(IAppContentProjectionSession sessionInternal) { mSessionInternal = sessionInternal; } /** * Notify the system that the content shared is not available anymore and the session must be * stopped. */ public void notifySessionStop() { try { mSessionInternal.notifySessionStop(); } catch (RemoteException e) { throw new RuntimeException(e); } } } media/java/android/media/projection/AppContentRequest.java 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * Copyright 2025 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.media.projection; import android.annotation.FlaggedApi; import android.util.Size; import androidx.annotation.NonNull; import java.util.List; import java.util.Objects; import java.util.function.Consumer; /** * Contains the requested characteristic for an app content projection. * <p> * An instance of this class is passed to * {@link AppContentProjectionService#onContentRequest(AppContentRequest)} * <p> * Available content must be returned by calling {@link #provideContent(List)}} */ @FlaggedApi(com.android.media.projection.flags.Flags.FLAG_APP_CONTENT_SHARING) public final class AppContentRequest { private final Size mThumbnailSize; private final Consumer<MediaProjectionAppContent[]> mContentConsumer; /** * @hide */ public AppContentRequest(@NonNull Size thumbnailSize, @NonNull Consumer<MediaProjectionAppContent[]> contentConsumer) { mThumbnailSize = Objects.requireNonNull(thumbnailSize); mContentConsumer = Objects.requireNonNull(contentConsumer); } /** * Used to return the content to the requester. The content passed here will replace any * previously provided content. * <p> * If no more content is available to offer, an empty list can be passed. */ public void provideContent(@NonNull List<MediaProjectionAppContent> content) { Objects.requireNonNull(content, "content must not be null. If all the content needs to be removed, an empty list" + " can be passed"); mContentConsumer.accept(content.toArray(new MediaProjectionAppContent[0])); } /** * @return The requested thumbnail size, in px, for each {@link MediaProjectionAppContent} * item. */ @NonNull public Size getThumbnailSize() { return mThumbnailSize; } } media/java/android/media/projection/IAppContentProjectionCallback.aidl 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 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.media.projection; import android.media.projection.MediaProjectionAppContent; import android.media.projection.IAppContentProjectionSession; import android.os.RemoteCallback; /** * @hide */ oneway interface IAppContentProjectionCallback { /** * Called when the picker UI has been shown to the user. * * @param newContentConsumer Consumer to update the list of displayed content * if needed. * @param thumbnailWidth The requested width of the app content thumbnail * @param thumbnailHeight The requested height of the app content thumbnail */ @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) void onContentRequest(in RemoteCallback newContentConsumer, int thumbnailWidth, int thumbnailHeight); /** * Called when the user picked a content to be shared within the requesting app. * This can be called multiple time if the user picked a different content to * be shared * * @return true if the request has been fulfilled, false otherwise. */ @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) void onLoopbackProjectionStarted(in IAppContentProjectionSession session, int contentId); /** * Called when the sharing session has been ended by the user or the system. The shared * resources can be discarded. */ @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) void onSessionStopped(); /** * Called when the user didn't pick some app content to be shared. This can happen if the * projection request was canceled, of the user picked another source (e.g. display, whole app). * <p> * Any resources created for sharing app content, such as thumbnail, can be discarded at this * point. */ @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) void onContentRequestCanceled(); } Loading
core/api/current.txt +21 −0 Original line number Diff line number Diff line Loading @@ -27364,6 +27364,25 @@ package android.media.midi { package android.media.projection { @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public abstract class AppContentProjectionService extends android.app.Service { ctor public AppContentProjectionService(); method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent); method public abstract void onContentRequest(@NonNull android.media.projection.AppContentRequest); method public abstract void onContentRequestCanceled(); method public abstract boolean onLoopbackProjectionStarted(@NonNull android.media.projection.AppContentProjectionSession, int); method public abstract void onSessionStopped(@NonNull android.media.projection.AppContentProjectionSession); field public static final String SERVICE_INTERFACE = "android.media.projection.AppContentProjectionService"; } @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public class AppContentProjectionSession { method public void notifySessionStop(); } @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public final class AppContentRequest { method @NonNull public android.util.Size getThumbnailSize(); method public void provideContent(@NonNull java.util.List<android.media.projection.MediaProjectionAppContent>); } public final class MediaProjection { method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, int, @Nullable android.view.Surface, @Nullable android.hardware.display.VirtualDisplay.Callback, @Nullable android.os.Handler); method public void registerCallback(@NonNull android.media.projection.MediaProjection.Callback, @Nullable android.os.Handler); Loading Loading @@ -27392,6 +27411,7 @@ package android.media.projection { method @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public int getInitiallySelectedSource(); method @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public int getProjectionSources(); method @FlaggedApi("com.android.media.projection.flags.app_content_sharing") @Nullable public CharSequence getRequesterHint(); method @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public boolean isOwnAppContentProvided(); method @FlaggedApi("com.android.media.projection.flags.app_content_sharing") public boolean isSourceEnabled(int); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.media.projection.MediaProjectionConfig> CREATOR; Loading @@ -27404,6 +27424,7 @@ package android.media.projection { ctor public MediaProjectionConfig.Builder(); method @NonNull public android.media.projection.MediaProjectionConfig build(); method @NonNull public android.media.projection.MediaProjectionConfig.Builder setInitiallySelectedSource(int); method @NonNull public android.media.projection.MediaProjectionConfig.Builder setOwnAppContentProvided(@NonNull android.content.Context, boolean); method @NonNull public android.media.projection.MediaProjectionConfig.Builder setRequesterHint(@Nullable String); method @NonNull public android.media.projection.MediaProjectionConfig.Builder setSourceEnabled(int, boolean); }
media/java/android/media/projection/AppContentProjectionService.java 0 → 100644 +203 −0 Original line number Diff line number Diff line /* * Copyright 2025 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.media.projection; import android.annotation.EnforcePermission; import android.annotation.FlaggedApi; import android.annotation.SdkConstant; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.IBinder; import android.os.PermissionEnforcer; import android.os.RemoteCallback; import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.media.projection.flags.Flags; import java.util.List; /** * Service to be implemented by the application providing the {@link MediaProjectionAppContent}. * * <p> * To receive media projection callbacks related to app content sharing, this service must: * <ol> * <li> be declared with an intent-filter action * {@value AppContentProjectionService#SERVICE_INTERFACE} * <li> set {@code android:exported="true"} * <li> be protected by {@value android.Manifest.permission#MANAGE_MEDIA_PROJECTION} * <li> set * {@link MediaProjectionConfig.Builder#setOwnAppContentProvided(Context, boolean)} to * {@code true} * </ol> * <p> * <pre> * </application> * ... * <service * android:exported="true" * android:name="com.example.AppContentSharingService" * android:permission="android.permission.MANAGE_MEDIA_PROJECTION"> * <intent-filter> * <action android:name="android.media.projection.AppContentProjectionService"/> * </intent-filter> * </service> * </application> * </pre> * <p> * Only holders of {@value android.Manifest.permission#MANAGE_MEDIA_PROJECTION} are allowed to call * these callbacks. */ @FlaggedApi(Flags.FLAG_APP_CONTENT_SHARING) public abstract class AppContentProjectionService extends Service { /** * The {@link Intent} action that must be declared as handled by the service. * Put this in your manifest to reply to requests for app content projection. */ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) public static final String SERVICE_INTERFACE = "android.media.projection.AppContentProjectionService"; /** @hide **/ public static final String EXTRA_APP_CONTENT = "extra_app_content"; private AppContentProjectionCallbackInternal mService; private class AppContentProjectionCallbackInternal extends IAppContentProjectionCallback.Stub { private AppContentProjectionSession mSession; private AppContentProjectionCallbackInternal(PermissionEnforcer permissionEnforcer) { super(permissionEnforcer); } @Override @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) public void onContentRequest(RemoteCallback newContentConsumer, int width, int height) { onContentRequest_enforcePermission(); AppContentProjectionService.this.onContentRequest( new AppContentRequest(new Size(width, height), mediaProjectionAppContents -> { Bundle bundle = new Bundle(); bundle.putParcelableArray(EXTRA_APP_CONTENT, mediaProjectionAppContents); newContentConsumer.sendResult(bundle); })); } @Override @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) public void onLoopbackProjectionStarted(IAppContentProjectionSession session, int contentId) { onLoopbackProjectionStarted_enforcePermission(); if (mSession != null) { throw new IllegalStateException( "Only one single AppContentProjectionSession is supported"); } mSession = new AppContentProjectionSession(session); AppContentProjectionService.this.onLoopbackProjectionStarted( mSession, contentId ); } @Override @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) public void onSessionStopped() { onSessionStopped_enforcePermission(); AppContentProjectionService.this.onSessionStopped(mSession); mSession = null; } @Override @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) public void onContentRequestCanceled() { onContentRequestCanceled_enforcePermission(); AppContentProjectionService.this.onContentRequestCanceled(); } } @NonNull @Override public final IBinder onBind(@Nullable Intent intent) { if (mService == null) { mService = new AppContentProjectionCallbackInternal(new PermissionEnforcer(this)); } return mService; } /** * Called when the picker UI has been shown to the user. * <p> * App content should be returned by calling {@link AppContentRequest#provideContent(List)} * <p> * If the user picks one of the offered app content, * {@link #onLoopbackProjectionStarted(AppContentProjectionSession, int)} will be called with * the id corresponding to the chosen content. See {@link MediaProjectionAppContent} for more * information about the id. * @param request the request instance containing the characteristics of the content requested */ public abstract void onContentRequest(@NonNull AppContentRequest request); /** * Called when the user picked a content to be shared within the requesting app. * * <p>This can be called multiple times if the user picks a different content to * be shared at a later point. * * <p> {@code contentId} is the id that has been provided by this application during the * {@link #onContentRequest(AppContentRequest)} call. See * {@link MediaProjectionAppContent} for more information about the id. * * @param session the session started for sharing the selected {@link MediaProjectionAppContent} * @param contentId the id of the selected {@link MediaProjectionAppContent} * * @return {@code true} if the request has been fulfilled, {@code false} otherwise */ public abstract boolean onLoopbackProjectionStarted( @NonNull AppContentProjectionSession session, int contentId); /** * Called when the sharing session has been ended by the user or the system. The shared * resources can be discarded. * * <p> The provided session object is the same as the one provided when * {@link #onLoopbackProjectionStarted(AppContentProjectionSession, int)} was called. It can * be used to identify the session that is being terminated. * * <p> Note that if the session is terminated by this service by calling * {@link AppContentProjectionSession#notifySessionStop()}, this callback won't be called. * * @param session the same session object that was passed in * {@link #onLoopbackProjectionStarted(AppContentProjectionSession, int)} */ public abstract void onSessionStopped(@NonNull AppContentProjectionSession session); /** * Called when the user didn't pick some app content to be shared. This can happen if the * projection request was canceled, or the user picked another source (e.g. display, whole app). * <p> * Any resources created for sharing app content, such as thumbnails, can be discarded at this * point. */ public abstract void onContentRequestCanceled(); }
media/java/android/media/projection/AppContentProjectionSession.java 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * Copyright 2025 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.media.projection; import android.annotation.FlaggedApi; import android.os.RemoteException; import com.android.media.projection.flags.Flags; /** * Represents a media projection session where the application receiving an instance of this class * is sharing its own content. * * <p> The application must use this class to notify if the sharing session terminates from its side * (e.g. the shared content is not available anymore). */ @FlaggedApi(Flags.FLAG_APP_CONTENT_SHARING) public class AppContentProjectionSession { private final IAppContentProjectionSession mSessionInternal; /** * @hide */ public AppContentProjectionSession(IAppContentProjectionSession sessionInternal) { mSessionInternal = sessionInternal; } /** * Notify the system that the content shared is not available anymore and the session must be * stopped. */ public void notifySessionStop() { try { mSessionInternal.notifySessionStop(); } catch (RemoteException e) { throw new RuntimeException(e); } } }
media/java/android/media/projection/AppContentRequest.java 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * Copyright 2025 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.media.projection; import android.annotation.FlaggedApi; import android.util.Size; import androidx.annotation.NonNull; import java.util.List; import java.util.Objects; import java.util.function.Consumer; /** * Contains the requested characteristic for an app content projection. * <p> * An instance of this class is passed to * {@link AppContentProjectionService#onContentRequest(AppContentRequest)} * <p> * Available content must be returned by calling {@link #provideContent(List)}} */ @FlaggedApi(com.android.media.projection.flags.Flags.FLAG_APP_CONTENT_SHARING) public final class AppContentRequest { private final Size mThumbnailSize; private final Consumer<MediaProjectionAppContent[]> mContentConsumer; /** * @hide */ public AppContentRequest(@NonNull Size thumbnailSize, @NonNull Consumer<MediaProjectionAppContent[]> contentConsumer) { mThumbnailSize = Objects.requireNonNull(thumbnailSize); mContentConsumer = Objects.requireNonNull(contentConsumer); } /** * Used to return the content to the requester. The content passed here will replace any * previously provided content. * <p> * If no more content is available to offer, an empty list can be passed. */ public void provideContent(@NonNull List<MediaProjectionAppContent> content) { Objects.requireNonNull(content, "content must not be null. If all the content needs to be removed, an empty list" + " can be passed"); mContentConsumer.accept(content.toArray(new MediaProjectionAppContent[0])); } /** * @return The requested thumbnail size, in px, for each {@link MediaProjectionAppContent} * item. */ @NonNull public Size getThumbnailSize() { return mThumbnailSize; } }
media/java/android/media/projection/IAppContentProjectionCallback.aidl 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 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.media.projection; import android.media.projection.MediaProjectionAppContent; import android.media.projection.IAppContentProjectionSession; import android.os.RemoteCallback; /** * @hide */ oneway interface IAppContentProjectionCallback { /** * Called when the picker UI has been shown to the user. * * @param newContentConsumer Consumer to update the list of displayed content * if needed. * @param thumbnailWidth The requested width of the app content thumbnail * @param thumbnailHeight The requested height of the app content thumbnail */ @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) void onContentRequest(in RemoteCallback newContentConsumer, int thumbnailWidth, int thumbnailHeight); /** * Called when the user picked a content to be shared within the requesting app. * This can be called multiple time if the user picked a different content to * be shared * * @return true if the request has been fulfilled, false otherwise. */ @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) void onLoopbackProjectionStarted(in IAppContentProjectionSession session, int contentId); /** * Called when the sharing session has been ended by the user or the system. The shared * resources can be discarded. */ @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) void onSessionStopped(); /** * Called when the user didn't pick some app content to be shared. This can happen if the * projection request was canceled, of the user picked another source (e.g. display, whole app). * <p> * Any resources created for sharing app content, such as thumbnail, can be discarded at this * point. */ @EnforcePermission(allOf = {"MANAGE_MEDIA_PROJECTION"}) void onContentRequestCanceled(); }