Revert "Added transparency-metadata display."
Revert "Added new transparency metadata enum." Revert submission 19943929-mba_ui Reason for revert: Feature cancelled due to product direction change. Reverted Changes: I7b3e296c3:Added transparency metadata feature flag. Ia4b2f294b:Added new transparency metadata enum. If7822100a:Added transparency-metadata display. Change-Id: If50179b4a485587dcf49a2c9e2ae18a69b173794
This commit is contained in:
@@ -4654,17 +4654,6 @@
|
|||||||
android:value="UsageStats"/>
|
android:value="UsageStats"/>
|
||||||
</activity-alias>
|
</activity-alias>
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name="com.android.settings.applications.mobilebundledapps.MobileBundledAppDetailsActivity"
|
|
||||||
android:label="@string/mobile_bundled_apps_details_title"
|
|
||||||
android:exported="true"
|
|
||||||
android:icon="@drawable/ic_homepage_connected_device">
|
|
||||||
<intent-filter android:priority="1">
|
|
||||||
<action android:name="android.settings.TRANSPARENCY_METADATA" />
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<!-- [b/197780098] Disable eager initialization of Jetpack libraries. -->
|
<!-- [b/197780098] Disable eager initialization of Jetpack libraries. -->
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.startup.InitializationProvider"
|
android:name="androidx.startup.InitializationProvider"
|
||||||
|
@@ -1,107 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
~ Copyright (C) 2022 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.
|
|
||||||
-->
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/app_details_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="10dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/contains_ads_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/mobile_bundled_apps_details_contains_ad_title"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/contains_ads"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/developer_info_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/mobile_bundled_apps_details_developer_info_title"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/developer_list"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/contact_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/mobile_bundled_apps_details_contact_title"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/contact_url"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/contact_email"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/description_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/mobile_bundled_apps_details_description_title"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/description"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/privacy_policy_url_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/mobile_bundled_apps_details_privacy_policy_title"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/privacy_policy_url"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/category_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/mobile_bundled_apps_details_category_title"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/category"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
</LinearLayout>
|
|
@@ -1,50 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
~ Copyright (C) 2022 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="10dp">
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/mba_info"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="14sp"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"/>
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/developer_name"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/developer_relationship"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/developer_email"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/developer_country"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
</LinearLayout>
|
|
@@ -11922,26 +11922,11 @@
|
|||||||
<!-- [CHAR LIMIT=NONE] Hint for QR code process failure -->
|
<!-- [CHAR LIMIT=NONE] Hint for QR code process failure -->
|
||||||
<string name="bt_le_audio_qr_code_is_not_valid_format">QR code isn\u0027t a valid format</string>
|
<string name="bt_le_audio_qr_code_is_not_valid_format">QR code isn\u0027t a valid format</string>
|
||||||
|
|
||||||
<!-- Mobile Bundled Apps Transparency Metadata-->
|
<!-- Accessibility Software Cursor -->
|
||||||
|
|
||||||
|
<!-- [CHAR LIMIT=NONE] Title for Accessibility Software Cursor setting for trigger hints. -->
|
||||||
|
<string name="software_cursor_trigger_hints_enabled_title" translatable="false">Gesture detection area hints</string>
|
||||||
|
<!-- [CHAR LIMIT=NONE] Title for Accessibility Software Cursor setting for keyboard shift. -->
|
||||||
|
<string name="software_cursor_trigger_keyboard_shift_enabled_title" translatable="false">Shift gesture detection region above keyboard</string>
|
||||||
|
|
||||||
<!-- [CHAR_LIMIT=NONE] Label for mobile bundled apps screen -->
|
|
||||||
<string name="mobile_bundled_apps">Mobile bundled apps</string>
|
|
||||||
<!-- [CHAR_LIMIT=NONE] Title for mobile bundled apps screen -->
|
|
||||||
<string name="mobile_bundled_apps_title">Mobile bundled apps</string>
|
|
||||||
<!-- [CHAR_LIMIT=NONE] Title for mobile bundled apps transparency information details screen -->
|
|
||||||
<string name="mobile_bundled_apps_details_title">Mobile bundled apps transparency info</string>
|
|
||||||
<!-- [CHAR_LIMIT=NONE] Subheading for mobile bundled apps transparency information details screen -->
|
|
||||||
<string name="mobile_bundled_apps_details_contains_ad_title">Contains ads</string>
|
|
||||||
<!-- [CHAR_LIMIT=NONE] Subheading for mobile bundled apps transparency information details screen -->
|
|
||||||
<string name="mobile_bundled_apps_details_developer_info_title">Developer(s) Information</string>
|
|
||||||
<!-- [CHAR_LIMIT=NONE] Subheading for mobile bundled apps transparency information details screen -->
|
|
||||||
<string name="mobile_bundled_apps_details_contact_title">Contact Information</string>
|
|
||||||
<!-- [CHAR_LIMIT=NONE] Subheading for mobile bundled apps transparency information details screen -->
|
|
||||||
<string name="mobile_bundled_apps_details_description_title">Description</string>
|
|
||||||
<!-- [CHAR_LIMIT=NONE] Subheading for mobile bundled apps transparency information details screen -->
|
|
||||||
<string name="mobile_bundled_apps_details_privacy_policy_title">Privacy Policy</string>
|
|
||||||
<!-- [CHAR_LIMIT=NONE] Subheading for mobile bundled apps transparency information details screen -->
|
|
||||||
<string name="mobile_bundled_apps_details_category_title">Category</string>
|
|
||||||
<!-- [CHAR_LIMIT=NONE] Summary for App Details in App Info page if app is mobile bundled app -->
|
|
||||||
<string name="app_install_details_mba_summary">Mobile Bundled App</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -1,26 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<!-- Copyright (C) 2022 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<PreferenceScreen
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:title="">
|
|
||||||
<com.android.settingslib.widget.LayoutPreference
|
|
||||||
android:key="metadata"
|
|
||||||
android:selectable="false"
|
|
||||||
android:layout="@layout/mobile_bundled_apps_details_fragment" />
|
|
||||||
</PreferenceScreen>
|
|
@@ -56,7 +56,6 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.SettingsPreferenceFragment;
|
import com.android.settings.SettingsPreferenceFragment;
|
||||||
import com.android.settings.applications.manageapplications.ManageApplications;
|
import com.android.settings.applications.manageapplications.ManageApplications;
|
||||||
import com.android.settings.applications.mobilebundledapps.ApplicationMetadataUtils;
|
|
||||||
import com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesDetailsPreferenceController;
|
import com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesDetailsPreferenceController;
|
||||||
import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureDetailPreferenceController;
|
import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureDetailPreferenceController;
|
||||||
import com.android.settings.core.SubSettingLauncher;
|
import com.android.settings.core.SubSettingLauncher;
|
||||||
@@ -163,8 +162,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
|||||||
use(AppInstallerInfoPreferenceController.class);
|
use(AppInstallerInfoPreferenceController.class);
|
||||||
installer.setPackageName(packageName);
|
installer.setPackageName(packageName);
|
||||||
installer.setParentFragment(this);
|
installer.setParentFragment(this);
|
||||||
installer.setMbaWithMetadataStatus(ApplicationMetadataUtils.getDefaultInstance(),
|
|
||||||
packageName);
|
|
||||||
use(AppInstallerPreferenceCategoryController.class).setChildren(Arrays.asList(installer));
|
use(AppInstallerPreferenceCategoryController.class).setChildren(Arrays.asList(installer));
|
||||||
use(AppNotificationPreferenceController.class).setParentFragment(this);
|
use(AppNotificationPreferenceController.class).setParentFragment(this);
|
||||||
|
|
||||||
|
@@ -16,50 +16,42 @@
|
|||||||
|
|
||||||
package com.android.settings.applications.appinfo;
|
package com.android.settings.applications.appinfo;
|
||||||
|
|
||||||
import static com.android.settings.applications.mobilebundledapps.MobileBundledAppDetailsActivity.ACTION_TRANSPARENCY_METADATA;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.provider.DeviceConfig;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
import com.android.settings.applications.AppStoreUtil;
|
import com.android.settings.applications.AppStoreUtil;
|
||||||
import com.android.settings.applications.mobilebundledapps.ApplicationMetadataUtils;
|
|
||||||
import com.android.settingslib.applications.AppUtils;
|
import com.android.settingslib.applications.AppUtils;
|
||||||
|
|
||||||
public class AppInstallerInfoPreferenceController extends AppInfoPreferenceControllerBase {
|
public class AppInstallerInfoPreferenceController extends AppInfoPreferenceControllerBase {
|
||||||
|
|
||||||
private static final String KEY_ENABLE_PROMPT = "enable_prompt";
|
|
||||||
private String mPackageName;
|
private String mPackageName;
|
||||||
private String mInstallerPackage;
|
private String mInstallerPackage;
|
||||||
private CharSequence mInstallerLabel;
|
private CharSequence mInstallerLabel;
|
||||||
private Boolean mAppIsMbaWithMetadata;
|
|
||||||
private Boolean mEnableMbaUiFlag = false;
|
|
||||||
|
|
||||||
public AppInstallerInfoPreferenceController(Context context, String key) {
|
public AppInstallerInfoPreferenceController(Context context, String key) {
|
||||||
super(context, key);
|
super(context, key);
|
||||||
updateFromDeviceConfigFlags();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAvailabilityStatus() {
|
public int getAvailabilityStatus() {
|
||||||
if (UserManager.get(mContext).isManagedProfile()
|
if (UserManager.get(mContext).isManagedProfile()) {
|
||||||
|| AppUtils.isMainlineModule(mContext.getPackageManager(), mPackageName)) {
|
|
||||||
return DISABLED_FOR_USER;
|
|
||||||
}
|
|
||||||
if (mInstallerLabel != null || (mAppIsMbaWithMetadata && mEnableMbaUiFlag)) {
|
|
||||||
return AVAILABLE;
|
|
||||||
}
|
|
||||||
return DISABLED_FOR_USER;
|
return DISABLED_FOR_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AppUtils.isMainlineModule(mContext.getPackageManager(), mPackageName)) {
|
||||||
|
return DISABLED_FOR_USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mInstallerLabel != null ? AVAILABLE : DISABLED_FOR_USER;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateState(final Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
final int detailsStringId = AppUtils.isInstant(mParent.getPackageInfo().applicationInfo)
|
final int detailsStringId = AppUtils.isInstant(mParent.getPackageInfo().applicationInfo)
|
||||||
? R.string.instant_app_details_summary
|
? R.string.instant_app_details_summary
|
||||||
: R.string.app_install_details_summary;
|
: R.string.app_install_details_summary;
|
||||||
@@ -68,52 +60,14 @@ public class AppInstallerInfoPreferenceController extends AppInfoPreferenceContr
|
|||||||
Intent intent = AppStoreUtil.getAppStoreLink(mContext, mInstallerPackage, mPackageName);
|
Intent intent = AppStoreUtil.getAppStoreLink(mContext, mInstallerPackage, mPackageName);
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
preference.setIntent(intent);
|
preference.setIntent(intent);
|
||||||
} else if (mAppIsMbaWithMetadata && mEnableMbaUiFlag) {
|
|
||||||
preference.setIntent(generateMetadataXmlViewerIntent());
|
|
||||||
preference.setSummary(mContext.getString(R.string.app_install_details_mba_summary));
|
|
||||||
} else {
|
} else {
|
||||||
preference.setEnabled(false);
|
preference.setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setPackageName(String packageName) {
|
||||||
* Sets the packageName in context for the controller.
|
|
||||||
*/
|
|
||||||
public void setPackageName(final String packageName) {
|
|
||||||
mPackageName = packageName;
|
mPackageName = packageName;
|
||||||
mInstallerPackage = AppStoreUtil.getInstallerPackageName(mContext, mPackageName);
|
mInstallerPackage = AppStoreUtil.getInstallerPackageName(mContext, mPackageName);
|
||||||
mInstallerLabel = Utils.getApplicationLabel(mContext, mInstallerPackage);
|
mInstallerLabel = Utils.getApplicationLabel(mContext, mInstallerPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Setups and determines if the current package in context is an mobile-bundled-app with
|
|
||||||
* an application metadata file embedded within.
|
|
||||||
*/
|
|
||||||
public void setMbaWithMetadataStatus(final ApplicationMetadataUtils appMetadataUtils,
|
|
||||||
final String packageName) {
|
|
||||||
mAppIsMbaWithMetadata = appMetadataUtils.packageContainsXmlFile(
|
|
||||||
mContext.getPackageManager(), packageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Intent generateMetadataXmlViewerIntent() {
|
|
||||||
final Intent metadataXmlIntent = new Intent(ACTION_TRANSPARENCY_METADATA)
|
|
||||||
.setPackage(mContext.getPackageName());
|
|
||||||
metadataXmlIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, mPackageName);
|
|
||||||
return metadataXmlIntent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateFromDeviceConfigFlags() {
|
|
||||||
String enablePromptFlag = DeviceConfig.getProperty(
|
|
||||||
DeviceConfig.NAMESPACE_TRANSPARENCY_METADATA,
|
|
||||||
KEY_ENABLE_PROMPT);
|
|
||||||
//No-op for empty field and relies on default value of false
|
|
||||||
if (!TextUtils.isEmpty(enablePromptFlag)) {
|
|
||||||
setEnableMbaFlag(Boolean.parseBoolean(enablePromptFlag));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
void setEnableMbaFlag(final boolean flagValue) {
|
|
||||||
mEnableMbaUiFlag = flagValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,201 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 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.settings.applications.mobilebundledapps;
|
|
||||||
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.NamedNodeMap;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.zip.ZipFile;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for parsing application-metadata.xml and return relevant fields
|
|
||||||
*/
|
|
||||||
public class ApplicationMetadataUtils {
|
|
||||||
private static final String TAG = ApplicationMetadataUtils.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final ApplicationMetadataUtils DEFAULT_INSTANCE = new ApplicationMetadataUtils();
|
|
||||||
private static final String TRANSPARENCY_XML_DIR = "APP-INF/application-metadata.xml";
|
|
||||||
private static final String DESCRIPTION_TAG = "description";
|
|
||||||
private static final String CONTAINS_ADS_TAG = "contains-ads";
|
|
||||||
private static final String PRIVACY_POLICY_TAG = "privacy-policy";
|
|
||||||
private static final String CONTACT_TAG = "contact";
|
|
||||||
private static final String CATEGORY_TAG = "category";
|
|
||||||
private static final String DEVELOPER_TAG = "developer";
|
|
||||||
private static final String URL_TAG = "url";
|
|
||||||
private static final String EMAIL_TAG = "email";
|
|
||||||
private static final String NAME_TAG = "name";
|
|
||||||
private static final String RELATIONSHIP_TAG = "relationship";
|
|
||||||
private static final String COUNTRY_TAG = "country";
|
|
||||||
|
|
||||||
private final PackageManager mPackageManager;
|
|
||||||
|
|
||||||
private Document mXmlDoc;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
ApplicationMetadataUtils() {
|
|
||||||
mPackageManager = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Need to create singleton factory as Android is unable to mock static for testing.
|
|
||||||
public static ApplicationMetadataUtils getDefaultInstance() {
|
|
||||||
return DEFAULT_INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a new instance that also provisions and reads the XML file.
|
|
||||||
*/
|
|
||||||
public static ApplicationMetadataUtils newInstance(final PackageManager packageManager,
|
|
||||||
String packageName) {
|
|
||||||
return new ApplicationMetadataUtils(packageManager, packageName);
|
|
||||||
}
|
|
||||||
private ApplicationMetadataUtils(final PackageManager packageManager,
|
|
||||||
final String packageName) {
|
|
||||||
mPackageManager = packageManager;
|
|
||||||
try (ZipFile apk = new ZipFile(getApkDirectory(packageName, mPackageManager))) {
|
|
||||||
mXmlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
|
||||||
.parse(apk.getInputStream(apk.getEntry(TRANSPARENCY_XML_DIR)));
|
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
void setXmlDoc(final Document xmlDoc) {
|
|
||||||
mXmlDoc = xmlDoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getApkDirectory(final String packageName,
|
|
||||||
final PackageManager packageManager)
|
|
||||||
throws PackageManager.NameNotFoundException {
|
|
||||||
return packageManager
|
|
||||||
.getApplicationInfo(packageName,
|
|
||||||
PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA))
|
|
||||||
.sourceDir;
|
|
||||||
}
|
|
||||||
public boolean getContainsAds() {
|
|
||||||
return mXmlDoc != null
|
|
||||||
&& mXmlDoc.getElementsByTagName(CONTAINS_ADS_TAG) != null
|
|
||||||
&& mXmlDoc.getElementsByTagName(CONTAINS_ADS_TAG).getLength() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPrivacyPolicyUrl() {
|
|
||||||
return retrieveElementAttributeValue(PRIVACY_POLICY_TAG, URL_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String retrieveElementAttributeValue(final String elementTag, final String attribute) {
|
|
||||||
try {
|
|
||||||
return mXmlDoc.getElementsByTagName(elementTag).item(0)
|
|
||||||
.getAttributes().getNamedItem(attribute).getNodeValue();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return retrieveElementValue(DESCRIPTION_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String retrieveElementValue(final String elementTag) {
|
|
||||||
try {
|
|
||||||
return mXmlDoc.getElementsByTagName(elementTag).item(0).getTextContent();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCategoryName() {
|
|
||||||
return retrieveElementAttributeValue(CATEGORY_TAG, NAME_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContactUrl() {
|
|
||||||
return retrieveElementAttributeValue(CONTACT_TAG, URL_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContactEmail() {
|
|
||||||
return retrieveElementAttributeValue(CONTACT_TAG, EMAIL_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPlayStoreUrl() {
|
|
||||||
return retrieveElementValue(DESCRIPTION_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the list of relevant major parties involved with this MBA
|
|
||||||
*/
|
|
||||||
public List<MbaDeveloper> getDevelopers() {
|
|
||||||
final List<MbaDeveloper> developersDetails = new ArrayList();
|
|
||||||
try {
|
|
||||||
final NodeList developers = mXmlDoc.getElementsByTagName(DEVELOPER_TAG);
|
|
||||||
if (developers == null) return developersDetails;
|
|
||||||
for (int i = 0; i < developers.getLength(); ++i) {
|
|
||||||
final NamedNodeMap developerAttributes = developers.item(i).getAttributes();
|
|
||||||
developersDetails.add(new MbaDeveloper(
|
|
||||||
developerAttributes.getNamedItem(NAME_TAG).getNodeValue(),
|
|
||||||
developerAttributes.getNamedItem(RELATIONSHIP_TAG).getNodeValue(),
|
|
||||||
developerAttributes.getNamedItem(EMAIL_TAG).getNodeValue(),
|
|
||||||
developerAttributes.getNamedItem(COUNTRY_TAG).getNodeValue()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
|
||||||
Log.d(TAG, e.getMessage());
|
|
||||||
}
|
|
||||||
return developersDetails;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if the a package can be parsed and extrapolate metadata from.
|
|
||||||
*/
|
|
||||||
public boolean packageContainsXmlFile(final PackageManager packageManager,
|
|
||||||
final String packageName) {
|
|
||||||
try (ZipFile apk = new ZipFile(getApkDirectory(packageName, packageManager))) {
|
|
||||||
return apk.getEntry(TRANSPARENCY_XML_DIR) != null;
|
|
||||||
} catch (final Exception e) {
|
|
||||||
Log.d(TAG, e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to return developer details
|
|
||||||
*/
|
|
||||||
public static class MbaDeveloper {
|
|
||||||
public final String name;
|
|
||||||
public final String relationship;
|
|
||||||
public final String email;
|
|
||||||
public final String country;
|
|
||||||
|
|
||||||
public MbaDeveloper(final String name,
|
|
||||||
final String relationship,
|
|
||||||
final String email,
|
|
||||||
final String country) {
|
|
||||||
this.name = name;
|
|
||||||
this.relationship = relationship;
|
|
||||||
this.email = email;
|
|
||||||
this.country = country;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 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.settings.applications.mobilebundledapps;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import com.android.settings.SettingsActivity;
|
|
||||||
/**
|
|
||||||
* An activity that is used to parse and display mobile-bundled apps application metadata xml file.
|
|
||||||
*/
|
|
||||||
public class MobileBundledAppDetailsActivity extends SettingsActivity {
|
|
||||||
public static final String ACTION_TRANSPARENCY_METADATA =
|
|
||||||
"android.settings.TRANSPARENCY_METADATA";
|
|
||||||
|
|
||||||
public MobileBundledAppDetailsActivity() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Intent getIntent() {
|
|
||||||
final Intent modIntent = new Intent(super.getIntent());
|
|
||||||
modIntent.setData(Uri.parse("package:"
|
|
||||||
+ super.getIntent().getExtra(Intent.EXTRA_PACKAGE_NAME).toString()));
|
|
||||||
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, MobileBundledAppsDetailsFragment.class.getName());
|
|
||||||
return modIntent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValidFragment(final String fragmentName) {
|
|
||||||
return MobileBundledAppsDetailsFragment.class.getName().equals(fragmentName);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 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.settings.applications.mobilebundledapps;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.app.settings.SettingsEnums;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.applications.AppInfoWithHeader;
|
|
||||||
import com.android.settings.applications.mobilebundledapps.ApplicationMetadataUtils.MbaDeveloper;
|
|
||||||
import com.android.settingslib.applications.ApplicationsState;
|
|
||||||
import com.android.settingslib.widget.LayoutPreference;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A fragment for retrieving the transparency metadata and PSL in the in-APK XML file and displaying
|
|
||||||
* them.
|
|
||||||
*/
|
|
||||||
public class MobileBundledAppsDetailsFragment extends AppInfoWithHeader {
|
|
||||||
private static final String METADATA_PREF_KEY = "metadata";
|
|
||||||
|
|
||||||
protected PackageManager mPackageManager;
|
|
||||||
private Context mContext;
|
|
||||||
private LayoutPreference mMetadataPreferenceView;
|
|
||||||
private ApplicationsState mApplicationState;
|
|
||||||
private boolean mCreated = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
mContext = getActivity();
|
|
||||||
mPackageManager = mContext.getPackageManager();
|
|
||||||
addPreferencesFromResource(R.xml.mobile_bundled_apps_details_preference);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
|
||||||
if (mCreated) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
final ApplicationMetadataUtils appUtil = ApplicationMetadataUtils.newInstance(
|
|
||||||
mPackageManager,
|
|
||||||
mPackageName);
|
|
||||||
if (mAppEntry == null) {
|
|
||||||
mApplicationState =
|
|
||||||
ApplicationsState.getInstance((Application) (mContext.getApplicationContext()));
|
|
||||||
mAppEntry = mApplicationState.getEntry(mPackageName, mContext.getUserId());
|
|
||||||
}
|
|
||||||
mMetadataPreferenceView = findPreference(METADATA_PREF_KEY);
|
|
||||||
createView(appUtil);
|
|
||||||
mCreated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createView(final ApplicationMetadataUtils appUtil) {
|
|
||||||
final LinearLayout devListLayout =
|
|
||||||
mMetadataPreferenceView.findViewById(R.id.developer_list);
|
|
||||||
populateDeveloperList(appUtil.getDevelopers(), devListLayout);
|
|
||||||
|
|
||||||
((TextView) mMetadataPreferenceView.findViewById(R.id.contains_ads))
|
|
||||||
.setText(Boolean.toString(appUtil.getContainsAds()));
|
|
||||||
|
|
||||||
((TextView) mMetadataPreferenceView.findViewById(R.id.contact_url))
|
|
||||||
.setText(appUtil.getContactUrl());
|
|
||||||
((TextView) mMetadataPreferenceView.findViewById(R.id.contact_email))
|
|
||||||
.setText(appUtil.getContactEmail());
|
|
||||||
|
|
||||||
((TextView) mMetadataPreferenceView.findViewById(R.id.privacy_policy_url))
|
|
||||||
.setText(appUtil.getPrivacyPolicyUrl());
|
|
||||||
|
|
||||||
((TextView) mMetadataPreferenceView.findViewById(R.id.description))
|
|
||||||
.setText(appUtil.getDescription());
|
|
||||||
|
|
||||||
((TextView) mMetadataPreferenceView.findViewById(R.id.category))
|
|
||||||
.setText(appUtil.getCategoryName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateDeveloperList(List<MbaDeveloper> developersDetails, ViewGroup parent) {
|
|
||||||
for (MbaDeveloper dev : developersDetails) {
|
|
||||||
View itemView = LayoutInflater.from(mContext)
|
|
||||||
.inflate(R.layout.mobile_bundled_apps_developer_fragment_row, parent, false);
|
|
||||||
|
|
||||||
((TextView) itemView.findViewById(R.id.developer_name)).setText(dev.name);
|
|
||||||
((TextView) itemView.findViewById(R.id.developer_relationship))
|
|
||||||
.setText(dev.relationship);
|
|
||||||
((TextView) itemView.findViewById(R.id.developer_email)).setText(dev.email);
|
|
||||||
((TextView) itemView.findViewById(R.id.developer_country)).setText(dev.country);
|
|
||||||
|
|
||||||
parent.addView(itemView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected AlertDialog createDialog(int id, int errorCode) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean refreshUi() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsCategory() {
|
|
||||||
return SettingsEnums.TRANSPARENCY_METADATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.settings.applications.appinfo;
|
package com.android.settings.applications.appinfo;
|
||||||
|
|
||||||
import static com.android.settings.applications.mobilebundledapps.MobileBundledAppDetailsActivity.ACTION_TRANSPARENCY_METADATA;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
@@ -43,14 +41,11 @@ import android.os.UserManager;
|
|||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
import com.android.settings.applications.mobilebundledapps.ApplicationMetadataUtils;
|
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.Captor;
|
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
@@ -58,8 +53,7 @@ import org.robolectric.RuntimeEnvironment;
|
|||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class AppInstallerInfoPreferenceControllerTest {
|
public class AppInstallerInfoPreferenceControllerTest {
|
||||||
private static final String TEST_PACKAGE_NAME = "Package1";
|
|
||||||
private static final String TEST_CONTEXT_KEY = "test_key";
|
|
||||||
@Mock
|
@Mock
|
||||||
private UserManager mUserManager;
|
private UserManager mUserManager;
|
||||||
@Mock
|
@Mock
|
||||||
@@ -73,17 +67,11 @@ public class AppInstallerInfoPreferenceControllerTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Preference mPreference;
|
private Preference mPreference;
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ApplicationMetadataUtils mApplicationMetadataUtils;
|
|
||||||
|
|
||||||
@Captor
|
|
||||||
ArgumentCaptor<Intent> mIntentArgumentCaptor;
|
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private AppInstallerInfoPreferenceController mController;
|
private AppInstallerInfoPreferenceController mController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws PackageManager.NameNotFoundException {
|
public void setUp() throws PackageManager.NameNotFoundException {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
|
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
|
||||||
@@ -93,13 +81,9 @@ public class AppInstallerInfoPreferenceControllerTest {
|
|||||||
when(mInstallSourceInfo.getInstallingPackageName()).thenReturn(installerPackage);
|
when(mInstallSourceInfo.getInstallingPackageName()).thenReturn(installerPackage);
|
||||||
when(mPackageManager.getApplicationInfo(eq(installerPackage), anyInt()))
|
when(mPackageManager.getApplicationInfo(eq(installerPackage), anyInt()))
|
||||||
.thenReturn(mAppInfo);
|
.thenReturn(mAppInfo);
|
||||||
mController = new AppInstallerInfoPreferenceController(mContext, TEST_CONTEXT_KEY);
|
mController = new AppInstallerInfoPreferenceController(mContext, "test_key");
|
||||||
|
mController.setPackageName("Package1");
|
||||||
mController.setParentFragment(mFragment);
|
mController.setParentFragment(mFragment);
|
||||||
mController.setPackageName(TEST_PACKAGE_NAME);
|
|
||||||
when(mApplicationMetadataUtils.packageContainsXmlFile(mPackageManager, TEST_PACKAGE_NAME))
|
|
||||||
.thenReturn(false);
|
|
||||||
mController.setMbaWithMetadataStatus(mApplicationMetadataUtils, TEST_PACKAGE_NAME);
|
|
||||||
mController.setEnableMbaFlag(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -111,42 +95,8 @@ public class AppInstallerInfoPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAvailabilityStatus_noAppLabel_andNotMbaWithMetadata_shouldReturnDisabled()
|
public void getAvailabilityStatus_noAppLabel_shouldReturnDisabled() {
|
||||||
throws PackageManager.NameNotFoundException {
|
|
||||||
when(mUserManager.isManagedProfile()).thenReturn(false);
|
when(mUserManager.isManagedProfile()).thenReturn(false);
|
||||||
mockMainlineModule(TEST_PACKAGE_NAME, false /* isMainlineModule */);
|
|
||||||
|
|
||||||
assertThat(mController.getAvailabilityStatus())
|
|
||||||
.isEqualTo(BasePreferenceController.DISABLED_FOR_USER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getAvailabilityStatus_noAppLabel_andHaveMbaFile_shouldReturnAvailable()
|
|
||||||
throws PackageManager.NameNotFoundException {
|
|
||||||
mController = new AppInstallerInfoPreferenceController(mContext, TEST_CONTEXT_KEY);
|
|
||||||
mController.setPackageName(TEST_PACKAGE_NAME);
|
|
||||||
mController.setParentFragment(mFragment);
|
|
||||||
when(mApplicationMetadataUtils.packageContainsXmlFile(mPackageManager, TEST_PACKAGE_NAME))
|
|
||||||
.thenReturn(true);
|
|
||||||
mController.setMbaWithMetadataStatus(mApplicationMetadataUtils, TEST_PACKAGE_NAME);
|
|
||||||
mockMainlineModule(TEST_PACKAGE_NAME, false /* isMainlineModule */);
|
|
||||||
|
|
||||||
assertThat(mController.getAvailabilityStatus())
|
|
||||||
.isEqualTo(BasePreferenceController.DISABLED_FOR_USER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getAvailabilityStatus_noAppLabel_andMbaFeatureFlagDisabled_shouldReturnDisabled()
|
|
||||||
throws PackageManager.NameNotFoundException {
|
|
||||||
mController.setEnableMbaFlag(false);
|
|
||||||
when(mUserManager.isManagedProfile()).thenReturn(false);
|
|
||||||
mController = new AppInstallerInfoPreferenceController(mContext, TEST_CONTEXT_KEY);
|
|
||||||
mController.setPackageName(TEST_PACKAGE_NAME);
|
|
||||||
mController.setParentFragment(mFragment);
|
|
||||||
when(mApplicationMetadataUtils.packageContainsXmlFile(mPackageManager, TEST_PACKAGE_NAME))
|
|
||||||
.thenReturn(true);
|
|
||||||
mController.setMbaWithMetadataStatus(mApplicationMetadataUtils, TEST_PACKAGE_NAME);
|
|
||||||
mockMainlineModule(TEST_PACKAGE_NAME, false /* isMainlineModule */);
|
|
||||||
|
|
||||||
assertThat(mController.getAvailabilityStatus())
|
assertThat(mController.getAvailabilityStatus())
|
||||||
.isEqualTo(BasePreferenceController.DISABLED_FOR_USER);
|
.isEqualTo(BasePreferenceController.DISABLED_FOR_USER);
|
||||||
@@ -155,12 +105,13 @@ public class AppInstallerInfoPreferenceControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getAvailabilityStatus_hasAppLabel_shouldReturnAvailable()
|
public void getAvailabilityStatus_hasAppLabel_shouldReturnAvailable()
|
||||||
throws PackageManager.NameNotFoundException {
|
throws PackageManager.NameNotFoundException {
|
||||||
|
final String packageName = "Package1";
|
||||||
when(mUserManager.isManagedProfile()).thenReturn(false);
|
when(mUserManager.isManagedProfile()).thenReturn(false);
|
||||||
when(mAppInfo.loadLabel(mPackageManager)).thenReturn("Label1");
|
when(mAppInfo.loadLabel(mPackageManager)).thenReturn("Label1");
|
||||||
mController = new AppInstallerInfoPreferenceController(mContext, TEST_CONTEXT_KEY);
|
mController = new AppInstallerInfoPreferenceController(mContext, "test_key");
|
||||||
mController.setPackageName(TEST_PACKAGE_NAME);
|
mController.setPackageName(packageName);
|
||||||
mController.setParentFragment(mFragment);
|
mController.setParentFragment(mFragment);
|
||||||
mockMainlineModule(TEST_PACKAGE_NAME, false /* isMainlineModule */);
|
mockMainlineModule(packageName, false /* isMainlineModule */);
|
||||||
|
|
||||||
assertThat(mController.getAvailabilityStatus())
|
assertThat(mController.getAvailabilityStatus())
|
||||||
.isEqualTo(BasePreferenceController.AVAILABLE);
|
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||||
@@ -178,7 +129,7 @@ public class AppInstallerInfoPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateState_noAppStoreLink_andNotMbaWithMetadata_shouldDisablePreference() {
|
public void updateState_noAppStoreLink_shouldDisablePreference() {
|
||||||
final PackageInfo packageInfo = mock(PackageInfo.class);
|
final PackageInfo packageInfo = mock(PackageInfo.class);
|
||||||
packageInfo.applicationInfo = mAppInfo;
|
packageInfo.applicationInfo = mAppInfo;
|
||||||
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
|
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
|
||||||
@@ -188,39 +139,6 @@ public class AppInstallerInfoPreferenceControllerTest {
|
|||||||
|
|
||||||
verify(mPreference).setEnabled(false);
|
verify(mPreference).setEnabled(false);
|
||||||
}
|
}
|
||||||
@Test
|
|
||||||
public void updateState_noAppStoreLink_andMbaFeatureFlagDisabled_shouldDisablePreference() {
|
|
||||||
mController.setEnableMbaFlag(false);
|
|
||||||
when(mApplicationMetadataUtils.packageContainsXmlFile(mPackageManager, TEST_PACKAGE_NAME))
|
|
||||||
.thenReturn(true);
|
|
||||||
mController.setMbaWithMetadataStatus(mApplicationMetadataUtils, TEST_PACKAGE_NAME);
|
|
||||||
final PackageInfo packageInfo = mock(PackageInfo.class);
|
|
||||||
packageInfo.applicationInfo = mAppInfo;
|
|
||||||
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
|
|
||||||
when(mPackageManager.resolveActivity(any(), anyInt())).thenReturn(null);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
verify(mPreference).setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void updateState_noAppStoreLink_andMbaWithMetadata_shouldSetPreferenceIntent() {
|
|
||||||
when(mApplicationMetadataUtils.packageContainsXmlFile(mPackageManager, TEST_PACKAGE_NAME))
|
|
||||||
.thenReturn(true);
|
|
||||||
mController.setMbaWithMetadataStatus(mApplicationMetadataUtils, TEST_PACKAGE_NAME);
|
|
||||||
final PackageInfo packageInfo = mock(PackageInfo.class);
|
|
||||||
packageInfo.applicationInfo = mAppInfo;
|
|
||||||
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
|
|
||||||
when(mPackageManager.resolveActivity(any(), anyInt())).thenReturn(null);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
verify(mPreference, never()).setEnabled(false);
|
|
||||||
verify(mPreference).setIntent(mIntentArgumentCaptor.capture());
|
|
||||||
assertThat(mIntentArgumentCaptor.getValue().getAction())
|
|
||||||
.isEqualTo(ACTION_TRANSPARENCY_METADATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateState_hasAppStoreLink_shouldSetPreferenceIntent() {
|
public void updateState_hasAppStoreLink_shouldSetPreferenceIntent() {
|
||||||
@@ -236,9 +154,7 @@ public class AppInstallerInfoPreferenceControllerTest {
|
|||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
verify(mPreference, never()).setEnabled(false);
|
verify(mPreference, never()).setEnabled(false);
|
||||||
verify(mPreference).setIntent(mIntentArgumentCaptor.capture());
|
verify(mPreference).setIntent(any(Intent.class));
|
||||||
assertThat(mIntentArgumentCaptor.getValue().getAction())
|
|
||||||
.isEqualTo(Intent.ACTION_SHOW_APP_INFO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -1,147 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 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.settings.applications.mobilebundledapps;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.any;
|
|
||||||
import static org.mockito.Mockito.eq;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.pm.ApplicationInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
|
|
||||||
import com.google.common.io.CharSource;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
public class ApplicationMetadataUtilsTest {
|
|
||||||
private static final String TEST_PACKAGE_NAME = "test";
|
|
||||||
private static final String TEST_SOURCE_DIR = "sourcedir";
|
|
||||||
|
|
||||||
private static final String TEST_XML_SCHEMA = "<transparency-info>\n"
|
|
||||||
+ " <template/>\n"
|
|
||||||
+ " <contains-ads/>\n"
|
|
||||||
+ " <developers>\n"
|
|
||||||
+ " <developer name=\"Example ODM\" relationship=\"ODM\" email=\"odm@example.com\""
|
|
||||||
+ " \n"
|
|
||||||
+ " website=\"http://odm.example.com\" country=\"US\"/>\n"
|
|
||||||
+ " <developer name=\"Example carrier\" relationship=\"CARRIER\" "
|
|
||||||
+ "email=\"carrier@example.com\" \n"
|
|
||||||
+ " country=\"US\"/>\n"
|
|
||||||
+ " </developers>\n"
|
|
||||||
+ " <contact url=\"http://example.com/contact-us\" email=\"contact@example.com\"/>\n"
|
|
||||||
+ " <privacy-policy url=\"https://www.example.com/privacy-policy.html\"/>\n"
|
|
||||||
+ " <description>This application provides the user with news "
|
|
||||||
+ "headlines</description>\n"
|
|
||||||
+ " <category name=\"News and magazines\"/>\n"
|
|
||||||
+ "</transparency-info>";
|
|
||||||
@Mock
|
|
||||||
private PackageManager mPackageManager;
|
|
||||||
|
|
||||||
private Document mDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
|
||||||
.parse(CharSource.wrap(TEST_XML_SCHEMA).asByteSource(StandardCharsets.UTF_8)
|
|
||||||
.openStream());
|
|
||||||
|
|
||||||
|
|
||||||
public ApplicationMetadataUtilsTest()
|
|
||||||
throws IOException, ParserConfigurationException, SAXException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup()
|
|
||||||
throws PackageManager.NameNotFoundException, IOException, ParserConfigurationException,
|
|
||||||
SAXException {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
final ApplicationInfo appInfo = new ApplicationInfo();
|
|
||||||
appInfo.sourceDir = TEST_SOURCE_DIR;
|
|
||||||
when(mPackageManager.getApplicationInfo(eq(TEST_PACKAGE_NAME),
|
|
||||||
any(PackageManager.ApplicationInfoFlags.class))).thenReturn(appInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getDefaultInstance_alwaysReturnSameInstance() {
|
|
||||||
final ApplicationMetadataUtils firstInstance =
|
|
||||||
ApplicationMetadataUtils.getDefaultInstance();
|
|
||||||
|
|
||||||
assertThat(firstInstance).isEqualTo(ApplicationMetadataUtils.getDefaultInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = RuntimeException.class)
|
|
||||||
public void createInstance_bubblesUpException() throws PackageManager.NameNotFoundException {
|
|
||||||
final String testErrorMsg = "test";
|
|
||||||
when(mPackageManager.getApplicationInfo(eq(TEST_PACKAGE_NAME),
|
|
||||||
any(PackageManager.ApplicationInfoFlags.class)))
|
|
||||||
.thenThrow(new Exception(testErrorMsg));
|
|
||||||
|
|
||||||
ApplicationMetadataUtils.newInstance(mPackageManager, TEST_PACKAGE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fieldGetters_toReturnNull_whenEmptyOrError() {
|
|
||||||
final ApplicationMetadataUtils appUtils = new ApplicationMetadataUtils();
|
|
||||||
assertThat(appUtils.getContainsAds()).isEqualTo(false);
|
|
||||||
assertThat(appUtils.getCategoryName()).isNull();
|
|
||||||
assertThat(appUtils.getPrivacyPolicyUrl()).isNull();
|
|
||||||
assertThat(appUtils.getDescription()).isNull();
|
|
||||||
assertThat(appUtils.getDevelopers()).isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fieldGetters_toReturnCorrectValues_whenExists() {
|
|
||||||
final ApplicationMetadataUtils appUtils = new ApplicationMetadataUtils();
|
|
||||||
appUtils.setXmlDoc(mDocument);
|
|
||||||
assertThat(appUtils.getContainsAds()).isEqualTo(true);
|
|
||||||
assertThat(appUtils.getCategoryName()).isEqualTo("News and magazines");
|
|
||||||
assertThat(appUtils.getPrivacyPolicyUrl())
|
|
||||||
.isEqualTo("https://www.example.com/privacy-policy.html");
|
|
||||||
assertThat(appUtils.getDescription())
|
|
||||||
.isEqualTo("This application provides the user with news headlines");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getDevelopers_returnsCorrectValues() {
|
|
||||||
final ApplicationMetadataUtils appUtils = new ApplicationMetadataUtils();
|
|
||||||
appUtils.setXmlDoc(mDocument);
|
|
||||||
final List<ApplicationMetadataUtils.MbaDeveloper> developers = appUtils.getDevelopers();
|
|
||||||
|
|
||||||
assertThat(developers.size()).isEqualTo(2);
|
|
||||||
assertThat(developers.get(0).country).isEqualTo("US");
|
|
||||||
assertThat(developers.get(0).email).isEqualTo("odm@example.com");
|
|
||||||
assertThat(developers.get(0).name).isEqualTo("Example ODM");
|
|
||||||
assertThat(developers.get(1).relationship).isEqualTo("CARRIER");
|
|
||||||
assertThat(developers.get(1).country).isEqualTo("US");
|
|
||||||
assertThat(developers.get(1).email).isEqualTo("carrier@example.com");
|
|
||||||
assertThat(developers.get(1).name).isEqualTo("Example carrier");
|
|
||||||
assertThat(developers.get(1).relationship).isEqualTo("CARRIER");
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user