Merge "Apply BLUETOOTH_ADMIN permission for BluetoothDeviceDetailActivity" into rvc-dev
diff --git a/res/layout/blob_list_item_view.xml b/res/layout/blob_list_item_view.xml
index 897d19c..339c8ef 100644
--- a/res/layout/blob_list_item_view.xml
+++ b/res/layout/blob_list_item_view.xml
@@ -47,4 +47,11 @@
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/>
+
+ <TextView
+ android:id="@+id/blob_size"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index d33aeee..21fae3e 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="yes" msgid="1999566976857398962">"\"Ja\""</string>
+ <string name="yes" msgid="1999566976857398962">"Ja"</string>
<string name="no" msgid="5541738710521607130">"Nein"</string>
<string name="create" msgid="986997212165228751">"Erstellen"</string>
<string name="allow" msgid="3763244945363657722">"Zulassen"</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 910aba4..de8ca8a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8706,6 +8706,11 @@
to the user's IT admin. [CHAR LIMIT=NONE] -->
<string name="interact_across_profiles_summary_2">Only connect apps if you trust them not to share personal data with your IT admin.</string>
+ <!-- Settings text. This text lets a user know that they can disconnect work and personal apps from
+ the Privacy page in settings, This is only shown when the connected app page is launched via
+ an app, not when navigated to via settings. [CHAR LIMIT=NONE] -->
+ <string name="interact_across_profiles_summary_3">You can disconnect apps anytime in your device\u2019s privacy settings.</string>
+
<!-- Dialog title. This dialog is shown when a user tries to connect a work app to a personal
app (e.g. their work Calendar to their personal Calendar), and it's confirming that they should
connect the apps only if they trust the work app with their personal data. [CHAR LIMIT=NONE] -->
@@ -9491,6 +9496,9 @@
<!-- Runtime permissions preference summary, shown when the app requests no permissions. [CHAR LIMIT=40] -->
<string name="runtime_permissions_summary_no_permissions_requested">No permissions requested</string>
+ <!-- Runtime permissions preference summary, which describes what the permission manager does. [CHAR LIMIT=40] -->
+ <string name="runtime_permissions_summary_control_app_access">Control app access to your data</string>
+
<!-- Label for showing all apps in list [CHAR LIMIT=30] -->
<string name="filter_all_apps">All apps</string>
<!-- Label for showing enabled apps in list [CHAR LIMIT=30] -->
diff --git a/res/xml/app_and_notification.xml b/res/xml/app_and_notification.xml
index 6e71f14..98b9844 100644
--- a/res/xml/app_and_notification.xml
+++ b/res/xml/app_and_notification.xml
@@ -77,9 +77,9 @@
<Preference
android:key="manage_perms"
android:title="@string/app_permissions"
+ android:summary="@string/runtime_permissions_summary_control_app_access"
android:order="12"
- settings:keywords="@string/keywords_app_permissions"
- settings:controller="com.android.settings.applications.AppPermissionsPreferenceController">
+ settings:keywords="@string/keywords_app_permissions">
<intent android:action="android.intent.action.MANAGE_PERMISSIONS"/>
</Preference>
diff --git a/res/xml/interact_across_profiles_permissions_details.xml b/res/xml/interact_across_profiles_permissions_details.xml
index c40eaf5..bf0ea8f 100644
--- a/res/xml/interact_across_profiles_permissions_details.xml
+++ b/res/xml/interact_across_profiles_permissions_details.xml
@@ -38,4 +38,9 @@
<Preference
android:summary="@string/interact_across_profiles_summary_2"
android:selectable="false" />
+
+ <Preference
+ android:key="interact_across_profiles_extra_summary"
+ android:summary="@string/interact_across_profiles_summary_3"
+ android:selectable="false"/>
</PreferenceScreen>
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index 81a6d09..c18a236 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -52,10 +52,9 @@
<Preference
android:key="privacy_manage_perms"
android:title="@string/app_permissions"
- android:summary="@string/summary_placeholder"
+ android:summary="@string/runtime_permissions_summary_control_app_access"
settings:allowDividerAbove="true"
- settings:searchable="false"
- settings:controller="com.android.settings.applications.AppPermissionsPreferenceController">
+ settings:searchable="false">
<intent android:action="android.intent.action.MANAGE_PERMISSIONS"/>
</Preference>
diff --git a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
index 1fe9fd6..71d9d13 100644
--- a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
+++ b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
@@ -63,6 +63,8 @@
"interact_across_profiles_settings_switch";
private static final String INTERACT_ACROSS_PROFILES_HEADER = "interact_across_profiles_header";
public static final String INSTALL_APP_BANNER_KEY = "install_app_banner";
+ public static final String INTERACT_ACROSS_PROFILE_EXTRA_SUMMARY_KEY =
+ "interact_across_profiles_extra_summary";
public static final String EXTRA_SHOW_FRAGMENT_ARGS = ":settings:show_fragment_args";
public static final String INTENT_KEY = "intent";
@@ -79,6 +81,7 @@
private boolean mInstalledInWork;
private String mAppLabel;
private Intent mInstallAppIntent;
+ private boolean mIsPageLaunchedByApp;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -106,6 +109,8 @@
mInstallBanner = findPreference(INSTALL_APP_BANNER_KEY);
mInstallBanner.setOnPreferenceClickListener(this);
+ mIsPageLaunchedByApp = launchedByApp();
+
// refreshUi checks that the user can still configure the appOp, return to the
// previous page if it can't.
if (!refreshUi()) {
@@ -113,14 +118,23 @@
}
addAppTitleAndIcons(mPersonalProfile, mWorkProfile);
styleActionBar();
+ maybeShowExtraSummary();
logPageLaunchMetrics();
}
+ private void maybeShowExtraSummary() {
+ Preference extraSummary = findPreference(INTERACT_ACROSS_PROFILE_EXTRA_SUMMARY_KEY);
+ if (extraSummary == null) {
+ return;
+ }
+ extraSummary.setVisible(mIsPageLaunchedByApp);
+ }
+
private void logPageLaunchMetrics() {
if (!mCrossProfileApps.canConfigureInteractAcrossProfiles(mPackageName)) {
logNonConfigurableAppMetrics();
}
- if (launchedByApp()) {
+ if (mIsPageLaunchedByApp) {
logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_APP);
} else {
logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_SETTINGS);
@@ -262,7 +276,7 @@
logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_USER_CONSENTED);
enableInteractAcrossProfiles(true);
refreshUi();
- if (launchedByApp()) {
+ if (mIsPageLaunchedByApp) {
setIntentAndFinish(/* appChanged= */ true);
}
}
diff --git a/src/com/android/settings/development/storage/BlobInfoListView.java b/src/com/android/settings/development/storage/BlobInfoListView.java
index 8e312a2..5457964 100644
--- a/src/com/android/settings/development/storage/BlobInfoListView.java
+++ b/src/com/android/settings/development/storage/BlobInfoListView.java
@@ -158,6 +158,7 @@
holder.blobId.setText(getString(R.string.blob_id_text, blob.getId()));
holder.blobExpiry.setText(getString(R.string.blob_expires_text,
SharedDataUtils.formatTime(blob.getExpiryTimeMs())));
+ holder.blobSize.setText(SharedDataUtils.formatSize(blob.getSizeBytes()));
return convertView;
}
}
diff --git a/src/com/android/settings/development/storage/BlobInfoViewHolder.java b/src/com/android/settings/development/storage/BlobInfoViewHolder.java
index de8c9a9..073a138 100644
--- a/src/com/android/settings/development/storage/BlobInfoViewHolder.java
+++ b/src/com/android/settings/development/storage/BlobInfoViewHolder.java
@@ -30,6 +30,7 @@
TextView blobLabel;
TextView blobId;
TextView blobExpiry;
+ TextView blobSize;
static BlobInfoViewHolder createOrRecycle(LayoutInflater inflater, View convertView) {
if (convertView != null) {
@@ -42,6 +43,7 @@
holder.blobLabel = convertView.findViewById(R.id.blob_label);
holder.blobId = convertView.findViewById(R.id.blob_id);
holder.blobExpiry = convertView.findViewById(R.id.blob_expiry);
+ holder.blobSize = convertView.findViewById(R.id.blob_size);
convertView.setTag(holder);
return holder;
}
diff --git a/src/com/android/settings/development/storage/LeaseInfoListView.java b/src/com/android/settings/development/storage/LeaseInfoListView.java
index ef9e5b8..b20bb65 100644
--- a/src/com/android/settings/development/storage/LeaseInfoListView.java
+++ b/src/com/android/settings/development/storage/LeaseInfoListView.java
@@ -93,11 +93,13 @@
final TextView blobLabel = headerView.findViewById(R.id.blob_label);
final TextView blobId = headerView.findViewById(R.id.blob_id);
final TextView blobExpiry = headerView.findViewById(R.id.blob_expiry);
+ final TextView blobSize = headerView.findViewById(R.id.blob_size);
blobLabel.setText(mBlobInfo.getLabel());
blobLabel.setTypeface(Typeface.DEFAULT_BOLD);
blobId.setText(getString(R.string.blob_id_text, mBlobInfo.getId()));
blobExpiry.setVisibility(View.GONE);
+ blobSize.setText(SharedDataUtils.formatSize(mBlobInfo.getSizeBytes()));
return headerView;
}
diff --git a/src/com/android/settings/development/storage/SharedDataUtils.java b/src/com/android/settings/development/storage/SharedDataUtils.java
index 2f48f6d..e0c038a 100644
--- a/src/com/android/settings/development/storage/SharedDataUtils.java
+++ b/src/com/android/settings/development/storage/SharedDataUtils.java
@@ -39,4 +39,9 @@
CALENDAR.setTimeInMillis(millis);
return FORMATTER.format(CALENDAR.getTime());
}
+
+ static String formatSize(long sizeBytes) {
+ final double sizeInMb = sizeBytes / (1024.0 * 1024.0);
+ return String.format("%.2f MB", sizeInMb);
+ }
}
diff --git a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java
index eb50b7c..6067b77 100644
--- a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java
+++ b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java
@@ -44,6 +44,7 @@
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
+import com.android.settingslib.search.SearchIndexableRaw;
import java.util.List;
@@ -134,34 +135,68 @@
updateTrustAgents();
}
+
+ @Override
+ public void updateDynamicRawDataToIndex(List<SearchIndexableRaw> rawData) {
+ if (!isAvailable()) {
+ return;
+ }
+
+ final List<TrustAgentManager.TrustAgentComponentInfo> agents = getActiveTrustAgents(
+ mContext);
+ if (agents == null) {
+ return;
+ }
+
+ for (int i = 0, size = agents.size(); i < size; i++) {
+ final SearchIndexableRaw raw = new SearchIndexableRaw(mContext);
+ final TrustAgentManager.TrustAgentComponentInfo agent = agents.get(i);
+
+ raw.key = PREF_KEY_TRUST_AGENT + i;
+ raw.title = agent.title;
+ rawData.add(raw);
+ }
+ }
+
+ /**
+ * @return The active trust agents from TrustAgentManager.
+ */
+ private List<TrustAgentManager.TrustAgentComponentInfo> getActiveTrustAgents(Context context) {
+ return mTrustAgentManager.getActiveTrustAgents(context, mLockPatternUtils);
+ }
+
private void updateTrustAgents() {
if (mSecurityCategory == null) {
return;
}
+ // If for some reason the preference is no longer available, don't proceed to add.
+ if (!isAvailable()) {
+ return;
+ }
+ final List<TrustAgentManager.TrustAgentComponentInfo> agents = getActiveTrustAgents(
+ mContext);
+ if (agents == null) {
+ return;
+ }
+
// First remove all old trust agents.
- while (true) {
- final Preference oldAgent = mSecurityCategory.findPreference(PREF_KEY_TRUST_AGENT);
+ for (int i = 0, size = agents.size(); i < size; i++) {
+ String key = PREF_KEY_TRUST_AGENT + i;
+ final Preference oldAgent = mSecurityCategory.findPreference(key);
if (oldAgent == null) {
break;
} else {
mSecurityCategory.removePreference(oldAgent);
}
}
- // If for some reason the preference is no longer available, don't proceed to add.
- if (!isAvailable()) {
- return;
- }
+
// Then add new ones.
final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID);
- final List<TrustAgentManager.TrustAgentComponentInfo> agents =
- mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils);
- if (agents == null) {
- return;
- }
- for (TrustAgentManager.TrustAgentComponentInfo agent : agents) {
+ for (int i = 0, size = agents.size(); i < size; i++) {
final RestrictedPreference trustAgentPreference =
new RestrictedPreference(mSecurityCategory.getContext());
- trustAgentPreference.setKey(PREF_KEY_TRUST_AGENT);
+ TrustAgentManager.TrustAgentComponentInfo agent = agents.get(i);
+ trustAgentPreference.setKey(PREF_KEY_TRUST_AGENT + i);
trustAgentPreference.setTitle(agent.title);
trustAgentPreference.setSummary(agent.summary);
// Create intent for this preference.
diff --git a/tests/robotests/src/com/android/settings/development/storage/SharedDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/storage/SharedDataPreferenceControllerTest.java
index f11fb39..c6a19c7 100644
--- a/tests/robotests/src/com/android/settings/development/storage/SharedDataPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/storage/SharedDataPreferenceControllerTest.java
@@ -113,7 +113,8 @@
accessors.add(two);
final List<BlobInfo> tmp = new ArrayList<>();
- tmp.add(new BlobInfo(10, System.currentTimeMillis(), "testing blob 1", accessors));
+ tmp.add(new BlobInfo(10, System.currentTimeMillis(), "testing blob 1", 54 * 1024 * 1024,
+ accessors));
return tmp;
}
}
diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java
index d9202d4..c0fbff7 100644
--- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java
@@ -44,6 +44,7 @@
import com.android.settings.security.SecuritySettings;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.search.SearchIndexableRaw;
import org.junit.Before;
import org.junit.Test;
@@ -111,10 +112,20 @@
@Test
public void onResume_shouldClearOldAgents() {
final Preference oldAgent = new Preference(mActivity);
- oldAgent.setKey(PREF_KEY_TRUST_AGENT);
- when(mCategory.findPreference(PREF_KEY_TRUST_AGENT))
+ oldAgent.setKey(PREF_KEY_TRUST_AGENT + 0);
+ when(mCategory.findPreference(PREF_KEY_TRUST_AGENT + 0))
.thenReturn(oldAgent)
.thenReturn(null);
+ final List<TrustAgentManager.TrustAgentComponentInfo> agents = new ArrayList<>();
+ final TrustAgentManager.TrustAgentComponentInfo agent =
+ mock(TrustAgentManager.TrustAgentComponentInfo.class);
+ agent.title = "Test_title";
+ agent.summary = "test summary";
+ agent.componentName = new ComponentName("pkg", "agent");
+ agent.admin = null;
+ agents.add(agent);
+ when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils))
+ .thenReturn(agents);
mController.displayPreference(mScreen);
mController.onResume();
@@ -160,4 +171,24 @@
verify(mCategory, never()).addPreference(any(Preference.class));
}
+
+ @Test
+ public void updateDynamicRawDataToIndex_shouldIndexAgents() {
+ final List<TrustAgentManager.TrustAgentComponentInfo> agents = new ArrayList<>();
+ final TrustAgentManager.TrustAgentComponentInfo agent =
+ mock(TrustAgentManager.TrustAgentComponentInfo.class);
+ agent.title = "Test_title";
+ agent.summary = "test summary";
+ agent.componentName = new ComponentName("pkg", "agent");
+ agent.admin = null;
+ agents.add(agent);
+ when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils))
+ .thenReturn(agents);
+ final List<SearchIndexableRaw> indexRaws = new ArrayList<>();
+
+ mController.updateDynamicRawDataToIndex(indexRaws);
+
+ assertThat(indexRaws).hasSize(1);
+ }
+
}