Snap for 9495384 from 96e6398e52 to udc-release

Change-Id: I544317ec625670dffccc3b4f1595711ed4df9f62
This commit is contained in:
Android Build Coastguard Worker
2023-01-17 04:27:00 +00:00
18 changed files with 348 additions and 69 deletions

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingBottom="16dp"
android:paddingTop="8dp">
<TextView
android:id="@+id/apps_top_intro_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textDirection="locale"
android:clickable="false"
android:longClickable="false"
android:textAppearance="@style/TextAppearance.TopIntroText"/>
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/illustration_lottie"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:visibility="visible"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_speed="1.5"/>
<TextView
android:id="@+id/app_list_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textDirection="locale"
android:clickable="false"
android:longClickable="false"
android:textAppearance="@style/TextAppearance.TopIntroText"/>
</LinearLayout>

1
res/raw/app_cloning.json Normal file

File diff suppressed because one or more lines are too long

View File

@@ -6577,6 +6577,9 @@
<string name="cloned_apps_dashboard_title">Cloned Apps</string>
<!-- Description for introduction of the cloned apps page [CHAR LIMIT=NONE]-->
<string name="desc_cloned_apps_intro_text">Create a second instance of an app so that you can use two accounts at the same time.</string>
<!-- Description while displaying cloneable app list in Cloned Apps page [CHAR LIMIT=NONE]-->
<string name="desc_cloneable_app_list_text">Apps that can be cloned.</string>
<!-- Summary for Cloned Apps menu [CHAR LIMIT=40] -->
<string name="cloned_apps_summary"><xliff:g id="cloned_apps_count">%1$s</xliff:g> cloned, <xliff:g id="allowed_apps_count">%2$d</xliff:g> available to clone</string>
<!-- Description for cloned apps removal title [CHAR LIMIT=40]-->
<string name="delete_all_app_clones">Delete all App clones</string>

View File

@@ -30,13 +30,12 @@
<PreferenceCategory
android:key="device_control_category"
android:title="@string/accessibility_hearing_device_control">
<SwitchPreference
android:key="hearing_aid_compatibility"
android:title="@string/accessibility_hac_mode_title"
android:summary="@string/accessibility_hac_mode_summary"
settings:searchable="true" />
settings:searchable="true"
settings:controller="com.android.settings.accessibility.HearingAidCompatibilityPreferenceController"/>
</PreferenceCategory>
<com.android.settings.accessibility.AccessibilityFooterPreference

View File

@@ -0,0 +1,78 @@
/*
* 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.accessibility;
import android.content.Context;
import android.media.AudioManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
/** Preference controller for Hearing Aid Compatibility (HAC) settings */
public class HearingAidCompatibilityPreferenceController extends TogglePreferenceController {
// Hearing Aid Compatibility settings values
static final String HAC_KEY = "HACSetting";
static final String HAC_VAL_ON = "ON";
static final String HAC_VAL_OFF = "OFF";
@VisibleForTesting
static final int HAC_DISABLED = 0;
@VisibleForTesting
static final int HAC_ENABLED = 1;
private final TelephonyManager mTelephonyManager;
private final AudioManager mAudioManager;
public HearingAidCompatibilityPreferenceController(Context context,
String preferenceKey) {
super(context, preferenceKey);
mTelephonyManager = context.getSystemService(TelephonyManager.class);
mAudioManager = context.getSystemService(AudioManager.class);
}
@Override
public int getAvailabilityStatus() {
return mTelephonyManager.isHearingAidCompatibilitySupported() ? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@Override
public boolean isChecked() {
final int hac = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.HEARING_AID, HAC_DISABLED);
return hac == HAC_ENABLED;
}
@Override
public boolean setChecked(boolean isChecked) {
setAudioParameterHacEnabled(isChecked);
return Settings.System.putInt(mContext.getContentResolver(), Settings.System.HEARING_AID,
(isChecked ? HAC_ENABLED : HAC_DISABLED));
}
@Override
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
private void setAudioParameterHacEnabled(boolean enabled) {
mAudioManager.setParameters(HAC_KEY + "=" + (enabled ? HAC_VAL_ON : HAC_VAL_OFF));
}
}

View File

@@ -121,11 +121,11 @@ public class AppBatteryPreferenceController extends BasePreferenceController
Log.i(TAG, "handlePreferenceTreeClick():\n" + mBatteryDiffEntry);
AdvancedPowerUsageDetail.startBatteryDetailPage(
mParent.getActivity(),
mParent,
mParent.getMetricsCategory(),
mBatteryDiffEntry,
Utils.formatPercentage(
mBatteryDiffEntry.getPercentOfTotal(), /* round */ true),
/*slotInformation=*/ null);
/*slotInformation=*/ null, /*showTimeInformation=*/ false);
return true;
}

View File

@@ -46,6 +46,9 @@ import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.widget.LottieColorUtils;
import com.airbnb.lottie.LottieAnimationView;
public class ApplicationViewHolder extends RecyclerView.ViewHolder {
@@ -113,6 +116,24 @@ public class ApplicationViewHolder extends RecyclerView.ViewHolder {
return view;
}
static View newHeaderWithAnimation(Context context, ViewGroup parent, int resIntroText,
int resAnimation, int resAppListText) {
ViewGroup view = (ViewGroup) LayoutInflater.from(parent.getContext())
.inflate(R.layout.preference_app_header_animation, parent, false);
TextView introText = view.findViewById(R.id.apps_top_intro_text);
introText.setText(resIntroText);
LottieAnimationView illustrationLottie = view.findViewById(R.id.illustration_lottie);
illustrationLottie.setAnimation(resAnimation);
illustrationLottie.setVisibility(View.VISIBLE);
LottieColorUtils.applyDynamicColors(context, illustrationLottie);
TextView appListText = view.findViewById(R.id.app_list_text);
appListText.setText(resAppListText);
return view;
}
void setSummary(CharSequence summary) {
mSummary.setText(summary);
updateSummaryVisibility();

View File

@@ -1376,8 +1376,9 @@ public class ManageApplications extends InstrumentedFragment
LIST_TYPE_NOTIFICATION);
} else if (mManageApplications.mListType == LIST_TYPE_CLONED_APPS
&& viewType == VIEW_TYPE_APP_HEADER) {
view = ApplicationViewHolder.newHeader(parent,
R.string.desc_cloned_apps_intro_text);
view = ApplicationViewHolder.newHeaderWithAnimation(mContext, parent,
R.string.desc_cloned_apps_intro_text, R.raw.app_cloning,
R.string.desc_cloneable_app_list_text);
} else if (mManageApplications.mListType == LIST_TYPE_CLONED_APPS
&& viewType == VIEW_TYPE_TWO_TARGET) {
view = ApplicationViewHolder.newView(

View File

@@ -139,13 +139,15 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
Activity caller, InstrumentedPreferenceFragment fragment,
BatteryDiffEntry diffEntry, String usagePercent, String slotInformation) {
startBatteryDetailPage(
caller, fragment.getMetricsCategory(), diffEntry, usagePercent, slotInformation);
caller, fragment.getMetricsCategory(), diffEntry, usagePercent, slotInformation,
/*showTimeInformation=*/ true);
}
/** Launches battery details page for an individual battery consumer fragment. */
public static void startBatteryDetailPage(
Context context, int sourceMetricsCategory,
BatteryDiffEntry diffEntry, String usagePercent, String slotInformation) {
BatteryDiffEntry diffEntry, String usagePercent, String slotInformation,
boolean showTimeInformation) {
final BatteryHistEntry histEntry = diffEntry.mBatteryHistEntry;
final LaunchBatteryDetailPageArgs launchArgs = new LaunchBatteryDetailPageArgs();
// configure the launch argument.
@@ -156,9 +158,11 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
launchArgs.mUid = (int) histEntry.mUid;
launchArgs.mIconId = diffEntry.getAppIconId();
launchArgs.mConsumedPower = (int) diffEntry.mConsumePower;
launchArgs.mForegroundTimeMs = diffEntry.mForegroundUsageTimeInMs;
launchArgs.mBackgroundTimeMs = diffEntry.mBackgroundUsageTimeInMs;
launchArgs.mScreenOnTimeMs = diffEntry.mScreenOnTimeInMs;
if (showTimeInformation) {
launchArgs.mForegroundTimeMs = diffEntry.mForegroundUsageTimeInMs;
launchArgs.mBackgroundTimeMs = diffEntry.mBackgroundUsageTimeInMs;
launchArgs.mScreenOnTimeMs = diffEntry.mScreenOnTimeInMs;
}
launchArgs.mIsUserEntry = histEntry.isUserEntry();
startBatteryDetailPage(context, sourceMetricsCategory, launchArgs);
}

View File

@@ -217,13 +217,16 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
}
private void showSpinnerAndAppList() {
removeAndCacheAllPreferences();
if (mBatteryDiffData == null) {
mHandler.post(() -> {
removeAndCacheAllPreferences();
});
return;
}
mSpinnerPreference.setVisible(true);
mAppListPreferenceGroup.setVisible(true);
mHandler.post(() -> {
removeAndCacheAllPreferences();
addAllPreferences();
});
}

View File

@@ -137,6 +137,16 @@ public final class DataProcessor {
// Wrap and processed history map into easy-to-use format for UI rendering.
final BatteryLevelData batteryLevelData =
getLevelDataThroughProcessedHistoryMap(context, processedBatteryHistoryMap);
// Loads the current battery usage data from the battery stats service.
final Map<String, BatteryHistEntry> currentBatteryHistoryMap =
getCurrentBatteryHistoryMapFromStatsService(context);
// Replaces the placeholder in processedBatteryHistoryMap.
for (Map.Entry<Long, Map<String, BatteryHistEntry>> mapEntry
: processedBatteryHistoryMap.entrySet()) {
if (mapEntry.getValue().containsKey(CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER)) {
mapEntry.setValue(currentBatteryHistoryMap);
}
}
return batteryLevelData == null
? null
: getBatteryUsageMap(

View File

@@ -32,20 +32,9 @@ public class CarrierConfigChangedReceiver extends BroadcastReceiver {
CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
private final CountDownLatch mLatch;
private final boolean mIsWaitingForValidSubId;
/**
* This is the CarrierConfigChanged receiver. If it receives the carrier config changed, then it
* call the CountDownLatch.countDown().
* If the "isWaitingForValidSubId" is true, then the receiver skip the carrier config changed
* with the subId = -1. The receiver executes the countDown when the CarrierConfigChanged
* with valid subId.
* If the "isWaitingForValidSubId" is false, then the receiver executes the countDown when
* receiving any CarrierConfigChanged.
*/
public CarrierConfigChangedReceiver(CountDownLatch latch, boolean isWaitingForValidSubId) {
public CarrierConfigChangedReceiver(CountDownLatch latch) {
mLatch = latch;
mIsWaitingForValidSubId = isWaitingForValidSubId;
}
public void registerOn(Context context) {
@@ -65,8 +54,7 @@ public class CarrierConfigChangedReceiver extends BroadcastReceiver {
}
private void checkSubscriptionIndex(Intent intent) {
if (intent.hasExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX)
|| !mIsWaitingForValidSubId) {
if (intent.hasExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX)) {
int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, -1);
Log.i(TAG, "subId from config changed: " + subId);
mLatch.countDown();

View File

@@ -140,8 +140,7 @@ public class UiccSlotUtil {
inactiveRemovableSlot,
/*removable sim's port Id*/ TelephonyManager.DEFAULT_PORT_INDEX,
excludedLogicalSlotIndex),
context,
/*isWaitingForValidSubId=*/ true);
context);
}
/**
@@ -179,8 +178,7 @@ public class UiccSlotUtil {
performSwitchToSlot(telMgr,
prepareUiccSlotMappings(uiccSlotMappings, /*slot is not psim*/ false,
physicalSlotId, port, excludedLogicalSlotIndex),
context,
/*isWaitingForValidSubId=*/ false);
context);
}
/**
@@ -232,8 +230,7 @@ public class UiccSlotUtil {
}
private static void performSwitchToSlot(TelephonyManager telMgr,
Collection<UiccSlotMapping> uiccSlotMappings, Context context,
boolean isWaitingForValidSubId)
Collection<UiccSlotMapping> uiccSlotMappings, Context context)
throws UiccSlotsException {
CarrierConfigChangedReceiver receiver = null;
long waitingTimeMillis =
@@ -243,7 +240,7 @@ public class UiccSlotUtil {
DEFAULT_WAIT_AFTER_SWITCH_TIMEOUT_MILLIS);
try {
CountDownLatch latch = new CountDownLatch(1);
receiver = new CarrierConfigChangedReceiver(latch, isWaitingForValidSubId);
receiver = new CarrierConfigChangedReceiver(latch);
receiver.registerOn(context);
telMgr.setSimSlotMapping(uiccSlotMappings);
latch.await(waitingTimeMillis, TimeUnit.MILLISECONDS);

View File

@@ -126,6 +126,7 @@ private class AppBatteryPresenter(private val context: Context, private val app:
this,
Utils.formatPercentage(percentOfTotal, true),
null,
false,
)
}

View File

@@ -18,16 +18,23 @@ package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.telephony.TelephonyManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
@@ -40,7 +47,16 @@ public class AccessibilityHearingAidsFragmentTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private TelephonyManager mTelephonyManager;
@Before
public void setUp() {
mTelephonyManager = spy(mContext.getSystemService(TelephonyManager.class));
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
doReturn(true).when(mTelephonyManager).isHearingAidCompatibilitySupported();
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {

View File

@@ -0,0 +1,130 @@
/*
* 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.accessibility;
import static com.android.settings.accessibility.HearingAidCompatibilityPreferenceController.HAC_DISABLED;
import static com.android.settings.accessibility.HearingAidCompatibilityPreferenceController.HAC_ENABLED;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.media.AudioManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link HearingAidCompatibilityPreferenceControllerTest}. */
@RunWith(RobolectricTestRunner.class)
public class HearingAidCompatibilityPreferenceControllerTest {
@Rule
public MockitoRule mocks = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private ContentResolver mContentResolver;
private TelephonyManager mTelephonyManager;
private AudioManager mAudioManager;
private final SwitchPreference mPreference = new SwitchPreference(mContext);
private HearingAidCompatibilityPreferenceController mController;
@Before
public void setUp() {
mTelephonyManager = spy(mContext.getSystemService(TelephonyManager.class));
mAudioManager = spy(mContext.getSystemService(AudioManager.class));
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
when(mContext.getSystemService(AudioManager.class)).thenReturn(mAudioManager);
mController = new HearingAidCompatibilityPreferenceController(mContext,
"hearing_aid_compatibility");
}
@Test
public void getAvailabilityStatus_HacSupported_shouldReturnAvailable() {
doReturn(true).when(mTelephonyManager).isHearingAidCompatibilitySupported();
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_HacNotSupported_shouldReturnUnsupported() {
doReturn(false).when(mTelephonyManager).isHearingAidCompatibilitySupported();
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void isChecked_enabledHac_shouldReturnTrue() {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.HEARING_AID,
HAC_ENABLED);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void isChecked_disabledHac_shouldReturnFalse() {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.HEARING_AID,
HAC_DISABLED);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_enabled_shouldEnableHac() {
mController.setChecked(true);
assertThat(Settings.System.getInt(mContext.getContentResolver(),
Settings.System.HEARING_AID, HAC_DISABLED)).isEqualTo(HAC_ENABLED);
verify(mAudioManager).setParameters("HACSetting=ON");
}
@Test
public void setChecked_disabled_shouldDisableHac() {
mController.setChecked(false);
assertThat(Settings.System.getInt(mContext.getContentResolver(),
Settings.System.HEARING_AID, HAC_DISABLED)).isEqualTo(HAC_DISABLED);
verify(mAudioManager).setParameters("HACSetting=OFF");
}
}

View File

@@ -162,6 +162,7 @@ class AppBatteryPreferenceTest {
batteryDiffEntry,
"10%",
null,
false,
)
}
}

View File

@@ -26,13 +26,9 @@ import android.os.Looper;
import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.testutils.ResourcesUtils;
import org.junit.Before;
import org.junit.Test;
import java.util.Locale;
public class NumberingPreferencesFragmentTest {
private Context mApplicationContext;
private NumberingPreferencesFragment mFragment;
@@ -47,37 +43,6 @@ public class NumberingPreferencesFragmentTest {
mFragment = new NumberingPreferencesFragment();
}
@Test
@UiThreadTest
public void initTitle_optionIsLanguageSelection_titleIsNumbers() {
Bundle bundle = new Bundle();
bundle.putString(RegionalPreferencesEntriesFragment.ARG_KEY_REGIONAL_PREFERENCE,
NumberingSystemItemController.ARG_VALUE_LANGUAGE_SELECT);
mFragment.setArguments(bundle);
String result = mFragment.initTitle();
assertEquals(ResourcesUtils.getResourcesString(
mApplicationContext, "numbers_preferences_title"), result);
}
@Test
@UiThreadTest
public void initTitle_optionIsNumberingSystemSelection_titleIsLocaleDisplayName() {
Locale expectedLocale = Locale.forLanguageTag("en-US");
Bundle bundle = new Bundle();
bundle.putString(RegionalPreferencesEntriesFragment.ARG_KEY_REGIONAL_PREFERENCE,
NumberingSystemItemController.ARG_VALUE_NUMBERING_SYSTEM_SELECT);
bundle.putString(
NumberingSystemItemController.KEY_SELECTED_LANGUAGE,
expectedLocale.toLanguageTag());
mFragment.setArguments(bundle);
String result = mFragment.initTitle();
assertEquals(expectedLocale.getDisplayName(expectedLocale), result);
}
@Test
@UiThreadTest
public void getMetricsCategory_optionIsLanguageSelection_resultIsLanguageSelection() {