diff options
author | 2023-05-18 15:51:31 +0000 | |
---|---|---|
committer | 2023-05-18 15:51:31 +0000 | |
commit | ca8950256d751fc02128be8d07414c13437b25a7 (patch) | |
tree | 249d6da2f8f66e42e04b764ed33eeb07b518b766 | |
parent | 408d8125ecbb408fdab00705a2102d665d2f1dac (diff) | |
parent | 96ef8c66444bd715a54ec87d9addfaba55de8d85 (diff) |
Merge "Add package menager for content protection" into udc-qpr-dev
3 files changed, 289 insertions, 0 deletions
diff --git a/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionPackageManager.java b/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionPackageManager.java new file mode 100644 index 000000000000..5221468e125a --- /dev/null +++ b/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionPackageManager.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2023 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 com.android.server.contentprotection; + +import android.Manifest; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.PackageManager.PackageInfoFlags; +import android.util.Slog; + +import java.util.Arrays; + +/** + * Basic package manager for content protection using content capture. + * + * @hide + */ +final class ContentProtectionPackageManager { + private static final String TAG = ContentProtectionPackageManager.class.getSimpleName(); + + private static final PackageInfoFlags PACKAGE_INFO_FLAGS = + PackageInfoFlags.of(PackageManager.GET_PERMISSIONS); + + @NonNull private final PackageManager mPackageManager; + + ContentProtectionPackageManager(@NonNull Context context) { + mPackageManager = context.getPackageManager(); + } + + @Nullable + public PackageInfo getPackageInfo(@NonNull String packageName) { + try { + return mPackageManager.getPackageInfo(packageName, PACKAGE_INFO_FLAGS); + } catch (NameNotFoundException ex) { + Slog.w(TAG, "Package info not found: ", ex); + return null; + } + } + + public boolean isSystemApp(@NonNull PackageInfo packageInfo) { + return packageInfo.applicationInfo != null && isSystemApp(packageInfo.applicationInfo); + } + + private boolean isSystemApp(@NonNull ApplicationInfo applicationInfo) { + return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + } + + public boolean isUpdatedSystemApp(@NonNull PackageInfo packageInfo) { + return packageInfo.applicationInfo != null + && isUpdatedSystemApp(packageInfo.applicationInfo); + } + + private boolean isUpdatedSystemApp(@NonNull ApplicationInfo applicationInfo) { + return (applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; + } + + public boolean hasRequestedInternetPermissions(@NonNull PackageInfo packageInfo) { + return packageInfo.requestedPermissions != null + && Arrays.asList(packageInfo.requestedPermissions) + .contains(Manifest.permission.INTERNET); + } +} diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index cfeaf0b54552..2b9a227be758 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -28,6 +28,7 @@ android_test { "services.accessibility", "services.appwidget", "services.autofill", + "services.contentcapture", "services.backup", "services.companion", "services.core", diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionPackageManagerTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionPackageManagerTest.java new file mode 100644 index 000000000000..7d45ea4ce39a --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionPackageManagerTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2023 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 com.android.server.contentprotection; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import android.Manifest.permission; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.PackageManager.PackageInfoFlags; +import android.testing.TestableContext; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +/** + * Test for {@link ContentProtectionPackageManager}. + * + * <p>Run with: {@code atest + * FrameworksServicesTests:com.android.server.contentprotection.ContentProtectionPackageManagerTest} + */ +@RunWith(AndroidJUnit4.class) +@SmallTest +public class ContentProtectionPackageManagerTest { + private static final String PACKAGE_NAME = "PACKAGE_NAME"; + + private static final PackageInfo EMPTY_PACKAGE_INFO = new PackageInfo(); + + private static final PackageInfo SYSTEM_APP_PACKAGE_INFO = createSystemAppPackageInfo(); + + private static final PackageInfo UPDATED_SYSTEM_APP_PACKAGE_INFO = + createUpdatedSystemAppPackageInfo(); + + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + + @Rule + public final TestableContext mContext = + new TestableContext(ApplicationProvider.getApplicationContext()); + + @Mock private PackageManager mMockPackageManager; + + private ContentProtectionPackageManager mContentProtectionPackageManager; + + @Before + public void setup() { + mContext.setMockPackageManager(mMockPackageManager); + mContentProtectionPackageManager = new ContentProtectionPackageManager(mContext); + } + + @Test + public void getPackageInfo_found() throws Exception { + PackageInfo expected = createPackageInfo(/* flags= */ 0); + when(mMockPackageManager.getPackageInfo(eq(PACKAGE_NAME), any(PackageInfoFlags.class))) + .thenReturn(expected); + + PackageInfo actual = mContentProtectionPackageManager.getPackageInfo(PACKAGE_NAME); + + assertThat(actual).isEqualTo(expected); + } + + @Test + public void getPackageInfo_notFound() throws Exception { + when(mMockPackageManager.getPackageInfo(eq(PACKAGE_NAME), any(PackageInfoFlags.class))) + .thenThrow(new NameNotFoundException()); + + PackageInfo actual = mContentProtectionPackageManager.getPackageInfo(PACKAGE_NAME); + + assertThat(actual).isNull(); + } + + @Test + public void getPackageInfo_null() { + PackageInfo actual = mContentProtectionPackageManager.getPackageInfo(PACKAGE_NAME); + + assertThat(actual).isNull(); + } + + @Test + public void isSystemApp_true() { + boolean actual = mContentProtectionPackageManager.isSystemApp(SYSTEM_APP_PACKAGE_INFO); + + assertThat(actual).isTrue(); + } + + @Test + public void isSystemApp_false() { + boolean actual = + mContentProtectionPackageManager.isSystemApp(UPDATED_SYSTEM_APP_PACKAGE_INFO); + + assertThat(actual).isFalse(); + } + + @Test + public void isSystemApp_noApplicationInfo() { + boolean actual = mContentProtectionPackageManager.isSystemApp(EMPTY_PACKAGE_INFO); + + assertThat(actual).isFalse(); + } + + @Test + public void isUpdatedSystemApp_true() { + boolean actual = + mContentProtectionPackageManager.isUpdatedSystemApp( + UPDATED_SYSTEM_APP_PACKAGE_INFO); + + assertThat(actual).isTrue(); + } + + @Test + public void isUpdatedSystemApp_false() { + boolean actual = + mContentProtectionPackageManager.isUpdatedSystemApp(SYSTEM_APP_PACKAGE_INFO); + + assertThat(actual).isFalse(); + } + + @Test + public void isUpdatedSystemApp_noApplicationInfo() { + boolean actual = mContentProtectionPackageManager.isUpdatedSystemApp(EMPTY_PACKAGE_INFO); + + assertThat(actual).isFalse(); + } + + @Test + public void hasRequestedInternetPermissions_true() { + PackageInfo packageInfo = createPackageInfo(new String[] {permission.INTERNET}); + + boolean actual = + mContentProtectionPackageManager.hasRequestedInternetPermissions(packageInfo); + + assertThat(actual).isTrue(); + } + + @Test + public void hasRequestedInternetPermissions_false() { + PackageInfo packageInfo = createPackageInfo(new String[] {permission.ACCESS_FINE_LOCATION}); + + boolean actual = + mContentProtectionPackageManager.hasRequestedInternetPermissions(packageInfo); + + assertThat(actual).isFalse(); + } + + @Test + public void hasRequestedInternetPermissions_noRequestedPermissions() { + boolean actual = + mContentProtectionPackageManager.hasRequestedInternetPermissions( + EMPTY_PACKAGE_INFO); + + assertThat(actual).isFalse(); + } + + private static PackageInfo createSystemAppPackageInfo() { + return createPackageInfo(ApplicationInfo.FLAG_SYSTEM); + } + + private static PackageInfo createUpdatedSystemAppPackageInfo() { + return createPackageInfo(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); + } + + private static PackageInfo createPackageInfo(int flags) { + return createPackageInfo(flags, /* requestedPermissions= */ new String[0]); + } + + private static PackageInfo createPackageInfo(String[] requestedPermissions) { + return createPackageInfo(/* flags= */ 0, requestedPermissions); + } + + private static PackageInfo createPackageInfo(int flags, String[] requestedPermissions) { + PackageInfo packageInfo = new PackageInfo(); + packageInfo.packageName = PACKAGE_NAME; + packageInfo.applicationInfo = new ApplicationInfo(); + packageInfo.applicationInfo.packageName = PACKAGE_NAME; + packageInfo.applicationInfo.flags = flags; + packageInfo.requestedPermissions = requestedPermissions; + return packageInfo; + } +} |