1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.providers.media.photopicker.v2; 18 19 import static com.android.providers.media.photopicker.v2.PickerUriResolverV2.ALBUM_PATH_SEGMENT; 20 import static com.android.providers.media.photopicker.v2.PickerUriResolverV2.AVAILABLE_PROVIDERS_PATH_SEGMENT; 21 import static com.android.providers.media.photopicker.v2.PickerUriResolverV2.MEDIA_PATH_SEGMENT; 22 import static com.android.providers.media.photopicker.v2.PickerUriResolverV2.PICKER_INTERNAL_PATH_SEGMENT; 23 import static com.android.providers.media.photopicker.v2.PickerUriResolverV2.PICKER_V2_PATH_SEGMENT; 24 import static com.android.providers.media.photopicker.v2.PickerUriResolverV2.UPDATE_PATH_SEGMENT; 25 26 import static java.util.Objects.requireNonNull; 27 28 import android.annotation.NonNull; 29 import android.content.ContentResolver; 30 import android.content.Context; 31 import android.net.Uri; 32 import android.provider.MediaStore; 33 import android.util.Log; 34 35 import com.android.providers.media.photopicker.PickerSyncController; 36 37 public class PickerNotificationSender { 38 private static final String TAG = "PickerNotificationSender"; 39 40 private static final Uri AVAILABLE_PROVIDERS_UPDATE_URI = new Uri.Builder() 41 .scheme(ContentResolver.SCHEME_CONTENT) 42 .authority(MediaStore.AUTHORITY) 43 .appendPath(PICKER_INTERNAL_PATH_SEGMENT) 44 .appendPath(PICKER_V2_PATH_SEGMENT) 45 .appendPath(AVAILABLE_PROVIDERS_PATH_SEGMENT) 46 .appendPath(UPDATE_PATH_SEGMENT) 47 .build(); 48 49 private static final Uri MEDIA_UPDATE_URI = new Uri.Builder() 50 .scheme(ContentResolver.SCHEME_CONTENT) 51 .authority(MediaStore.AUTHORITY) 52 .appendPath(PICKER_INTERNAL_PATH_SEGMENT) 53 .appendPath(PICKER_V2_PATH_SEGMENT) 54 .appendPath(MEDIA_PATH_SEGMENT) 55 .appendPath(UPDATE_PATH_SEGMENT) 56 .build(); 57 58 private static final Uri ALBUM_UPDATE_URI = new Uri.Builder() 59 .scheme(ContentResolver.SCHEME_CONTENT) 60 .authority(MediaStore.AUTHORITY) 61 .appendPath(PICKER_INTERNAL_PATH_SEGMENT) 62 .appendPath(PICKER_V2_PATH_SEGMENT) 63 .appendPath(ALBUM_PATH_SEGMENT) 64 .appendPath(UPDATE_PATH_SEGMENT) 65 .build(); 66 67 /** 68 * Send media update notification to the registered {@link android.database.ContentObserver}-s. 69 * @param context The application context. 70 */ notifyAvailableProvidersChange(@onNull Context context)71 public static void notifyAvailableProvidersChange(@NonNull Context context) { 72 Log.d(TAG, "Sending a notification for available providers update"); 73 context.getContentResolver() 74 .notifyChange(AVAILABLE_PROVIDERS_UPDATE_URI, /* observer= */ null); 75 } 76 77 /** 78 * Send media update notification to the registered {@link android.database.ContentObserver}-s. 79 * @param context The application context. 80 */ notifyMediaChange(@onNull Context context)81 public static void notifyMediaChange(@NonNull Context context) { 82 Log.d(TAG, "Sending a notification for media update"); 83 context.getContentResolver().notifyChange(MEDIA_UPDATE_URI, /* observer= */ null); 84 notifyMergedAlbumMediaChange(context, PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY); 85 } 86 87 /** 88 * Send album media update notification to the registered 89 * {@link android.database.ContentObserver}-s. 90 * @param context The application context. 91 * @param albumAuthority authority of the updated album 92 * @param albumId ID of the updated album 93 */ notifyAlbumMediaChange( @onNull Context context, @NonNull String albumAuthority, @NonNull String albumId)94 public static void notifyAlbumMediaChange( 95 @NonNull Context context, 96 @NonNull String albumAuthority, 97 @NonNull String albumId) { 98 Log.d(TAG, "Sending a notification for album media update " + albumId); 99 context.getContentResolver().notifyChange( 100 getAlbumMediaUpdateUri(albumAuthority, albumId), 101 /* observer= */ null); 102 } 103 104 /** 105 * Send album media update notification to the registered 106 * {@link android.database.ContentObserver}-s for all merged album updates. 107 * @param context The application context. 108 * @param localAuthority authority of the local provider. 109 */ notifyMergedAlbumMediaChange( @onNull Context context, @NonNull String localAuthority)110 public static void notifyMergedAlbumMediaChange( 111 @NonNull Context context, 112 @NonNull String localAuthority) { 113 for (String mergedAlbumId: PickerDataLayerV2.sMergedAlbumIds) { 114 Log.d(TAG, "Sending a notification for merged album media update " + mergedAlbumId); 115 116 // By default, always keep merged album authority as local. 117 notifyAlbumMediaChange(context, localAuthority, mergedAlbumId); 118 } 119 } 120 getAlbumMediaUpdateUri( @onNull String albumAuthority, @NonNull String albumId)121 private static Uri getAlbumMediaUpdateUri( 122 @NonNull String albumAuthority, 123 @NonNull String albumId) { 124 return ALBUM_UPDATE_URI 125 .buildUpon() 126 .appendPath(requireNonNull(albumAuthority)) 127 .appendPath(requireNonNull(albumId)) 128 .build(); 129 } 130 } 131