Snap for 7321546 from d3de9a1352 to sc-release

Change-Id: Idd78c814f0a7c08d0f34850f5e87950ff59f2ba0
This commit is contained in:
android-build-team Robot
2021-04-29 01:09:40 +00:00
25 changed files with 583 additions and 217 deletions

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2021 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:tint="?android:attr/colorControlNormal">
<path android:pathData="M0 0h24v24H0V0z" />
<path
android:fillColor="#000000"
android:pathData="M16 18H6V6h10v1h2V3c0-1.1-0.9-2-2-2L6 1.01C4.9 1.01 4 1.9 4 3v18c0 1.1 0.9
2 2 2h10c1.1 0 2-0.9 2-2v-4h-2v1zM6
3h10v1H6V3zm0 18v-1h10v1H6zm13.25-10.5v-0.66c0-1.13-1.03-2.09-2.25-2.09s-2.25 0.96 -2.25
2.09v0.66H14V16h6v-5.5h-0.75zm-1.5 0h-1.5v-0.66c0-0.29 0.38 -0.59 0.75 -0.59s0.75 0.3 0.75
0.59 v0.66z" />
</vector>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2021 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path
android:pathData="M0 0h24v24H0V0z" />
<path
android:fillColor="#000000"
android:pathData="M17 7h-4v2h4c1.65 0 3 1.35 3 3s-1.35 3-3 3h-4v2h4c2.76 0 5-2.24
5-5s-2.24-5-5-5zm-6 8H7c-1.65 0-3-1.35-3-3s1.35-3 3-3h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5
5h4v-2zm-3-4h8v2H8z" />
</vector>

View File

@@ -55,6 +55,56 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- How it works -->
<com.google.android.setupdesign.view.RichTextView
style="@style/SudDescription.Glif"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
android:paddingTop="12dp"
android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_title_2" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="12dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_fingerprint_24dp"/>
<Space
android:layout_width="24dp"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_message_2" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="12dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_device_locked_24dp"/>
<Space
android:layout_width="24dp"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_message_3" />
</LinearLayout>
<!-- You're in control -->
<com.google.android.setupdesign.view.RichTextView
style="@style/SudDescription.Glif"
android:layout_width="match_parent"
@@ -73,24 +123,16 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_fingerprint_introduction_shield_24dp"/>
android:src="@drawable/ic_trash_can"/>
<Space
android:layout_width="24dp"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_introduction_footer_message_1" />
android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_message_4" />
</LinearLayout>
<TextView
style="@style/SudDescription.Glif"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
android:paddingTop="24dp"
android:text="@string/security_settings_fingerprint_enroll_introduction_footer_title_2" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -101,34 +143,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_info_outline_24dp"/>
android:src="@drawable/ic_link_24dp"/>
<Space
android:layout_width="24dp"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_introduction_footer_message_2" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="24dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_fingerprint_24dp"/>
<Space
android:layout_width="24dp"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_introduction_footer_message_3" />
android:text="@string/security_settings_fingerprint_v2_enroll_introduction_message_learn_more" />
</LinearLayout>
</LinearLayout>

View File

@@ -51,7 +51,7 @@
android:inputType="textFilter|textUri"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginStart="3dp"
android:layout_marginEnd="8dp"
android:minHeight="@dimen/developer_option_dialog_min_height"/>
</RadioGroup>

View File

@@ -945,9 +945,9 @@
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_2">Fingerprint Unlock creates a unique model of your fingerprint to recognize you during authentication. To create this fingerprint model during setup, you will take images of your fingerprint from different positions.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_3">The phone will also use images from your interactions with Fingerprint Unlock to update your fingerprint model. Your fingerprint images and model are stored securely on your phone and never leave the phone. All processing occurs securely on your phone.</string>
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_3">The phone will also use images from your interactions with Fingerprint Unlock to update your fingerprint model. Images used to create your fingerprint model are never stored, but the fingerprint model is stored securely on your phone and never leaves the phone. All processing occurs securely on your phone.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_4">You can delete your fingerprint images and model, or turn off Fingerprint Unlock at any time in Settings. Fingerprint images and models are stored on the phone until you delete them.</string>
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_4">You can delete your fingerprint model, or turn off Fingerprint Unlock at any time in Settings. Fingerprint models are stored on the phone until you delete them.</string>
<!-- Introduction detail message shown in fingerprint enrollment introduction to learn more about fingerprint [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_v2_enroll_introduction_message_learn_more"></string>
@@ -6466,7 +6466,7 @@
<!-- [CHAR_LIMIT=NONE] Battery usage item for background usage time -->
<string name="battery_usage_for_background_time">Background: <xliff:g id="time">%s</xliff:g></string>
<!-- [CHAR_LIMIT=NONE] Battery usage main screen footer contentt -->
<string name="battery_usage_screen_footer">Battery usage data is approximate</string>
<string name="battery_usage_screen_footer">Battery usage data is approximate and doesn\'t measure usage when phone is charging</string>
<!-- Process Stats strings -->
<skip />

View File

@@ -77,6 +77,7 @@ import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.Spannable;
@@ -109,6 +110,7 @@ import androidx.preference.PreferenceGroup;
import com.android.internal.app.UnlaunchableAppActivity;
import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.core.FeatureFlags;
import com.android.settings.dashboard.profileselector.ProfileFragmentBridge;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.password.ChooseLockSettingsHelper;
@@ -159,6 +161,9 @@ public final class Utils extends com.android.settingslib.Utils {
/** Whether or not app hibernation is enabled on the device **/
public static final String PROPERTY_APP_HIBERNATION_ENABLED = "app_hibernation_enabled";
/** Whether or not Settings Shared Axis transition is enabled */
public static final String SETTINGS_SHARED_AXIS_ENABLED = "settings_shared_axis_enabled";
/**
* Finds a matching activity for a preference's intent. If a matching
* activity is not found, it will remove the preference.
@@ -1196,4 +1201,12 @@ public final class Utils extends com.android.settingslib.Utils {
public static boolean isProviderModelEnabled(Context context) {
return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL);
}
public static boolean isPageTransitionEnabled(Context context) {
final boolean isSilkyHome = FeatureFlagUtils.isEnabled(context, FeatureFlags.SILKY_HOME);
final boolean isTransitionEnabled = Settings.Global.getInt(context.getContentResolver(),
SETTINGS_SHARED_AXIS_ENABLED, 0) == 1;
return isSilkyHome && isTransitionEnabled;
}
}

View File

@@ -63,7 +63,7 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment {
boolean mIsStartTethering = false;
private UsbConnectionBroadcastReceiver mUsbReceiver;
private Handler mHandler = new Handler();
private Handler mHandler;
private boolean mIsConnected = false;
@VisibleForTesting
@@ -71,14 +71,17 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment {
(connected, functions, powerRole, dataRole) -> {
final long defaultFunctions = mUsbBackend.getDefaultUsbFunctions();
Log.d(TAG, "UsbConnectionListener() connected : " + connected + ", functions : "
+ functions + ", defaultFunctions : " + defaultFunctions);
if (connected && !mIsConnected && defaultFunctions == UsbManager.FUNCTION_RNDIS) {
+ functions + ", defaultFunctions : " + defaultFunctions
+ ", mIsStartTethering : " + mIsStartTethering);
if (connected && !mIsConnected && defaultFunctions == UsbManager.FUNCTION_RNDIS
&& !mIsStartTethering) {
startTethering();
}
if (mIsStartTethering) {
if (mIsStartTethering && connected) {
mCurrentFunctions = functions;
refresh(functions);
mUsbBackend.setDefaultUsbFunctions(functions);
mIsStartTethering = false;
}
mIsConnected = connected;
@@ -91,6 +94,7 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment {
mTetheringManager = context.getSystemService(TetheringManager.class);
mUsbReceiver = new UsbConnectionBroadcastReceiver(context, mUsbConnectionListener,
mUsbBackend);
mHandler = new Handler(context.getMainLooper());
getSettingsLifecycle().addObserver(mUsbReceiver);
mCurrentFunctions = mUsbBackend.getDefaultUsbFunctions();
}

View File

@@ -57,7 +57,7 @@ public class UsbDetailsFunctionsController extends UsbDetailsController
private PreferenceCategory mProfilesContainer;
private TetheringManager mTetheringManager;
private Handler mHandler = new Handler();
private Handler mHandler;
@VisibleForTesting
OnStartTetheringCallback mOnStartTetheringCallback;
@VisibleForTesting
@@ -69,6 +69,7 @@ public class UsbDetailsFunctionsController extends UsbDetailsController
mTetheringManager = context.getSystemService(TetheringManager.class);
mOnStartTetheringCallback = new OnStartTetheringCallback();
mPreviousFunction = mUsbBackend.getCurrentFunctions();
mHandler = new Handler(context.getMainLooper());
}
@Override

View File

@@ -18,6 +18,7 @@ package com.android.settings.core;
import android.annotation.LayoutRes;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -27,6 +28,7 @@ import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.FeatureFlagUtils;
@@ -43,10 +45,13 @@ import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settings.dashboard.CategoryManager;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.transition.SettingsTransitionHelper;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.resources.TextAppearanceConfig;
import com.google.android.setupcompat.util.WizardManagerHelper;
import com.google.android.setupdesign.util.ThemeHelper;
@@ -60,6 +65,7 @@ public class SettingsBaseActivity extends FragmentActivity {
protected static final boolean DEBUG_TIMING = false;
private static final String TAG = "SettingsBaseActivity";
private static final String DATA_SCHEME_PKG = "package";
private static final int DEFAULT_REQUEST = -1;
// Serves as a temporary list of tiles to ignore until we heard back from the PM that they
// are disabled.
@@ -73,6 +79,13 @@ public class SettingsBaseActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (Utils.isPageTransitionEnabled(this)) {
// Enable Activity transitions
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
SettingsTransitionHelper.applyForwardTransition(this);
SettingsTransitionHelper.applyBackwardTransition(this);
}
super.onCreate(savedInstanceState);
if (isLockTaskModePinned() && !isSettingsRunOnTop()) {
Log.w(TAG, "Devices lock task mode pinned.");
@@ -80,6 +93,7 @@ public class SettingsBaseActivity extends FragmentActivity {
}
final long startTime = System.currentTimeMillis();
getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
TextAppearanceConfig.setShouldLoadFontSynchronously(true);
final TypedArray theme = getTheme().obtainStyledAttributes(android.R.styleable.Theme);
if (!theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) {
@@ -122,6 +136,57 @@ public class SettingsBaseActivity extends FragmentActivity {
return true;
}
@Override
public void startActivity(Intent intent) {
if (!Utils.isPageTransitionEnabled(this)) {
super.startActivity(intent);
return;
}
super.startActivity(intent, getActivityOptionsBundle());
}
@Override
public void startActivity(Intent intent, @androidx.annotation.Nullable Bundle options) {
if (!Utils.isPageTransitionEnabled(this) || options != null) {
super.startActivity(intent, options);
return;
}
super.startActivity(intent, getActivityOptionsBundle());
}
@Override
public void startActivityForResult(Intent intent, int requestCode) {
// startActivity() will eventually calls startActivityForResult() with requestCode -1.
// Adding this condition to avoid multiple calls.
if (!Utils.isPageTransitionEnabled(this) || requestCode == DEFAULT_REQUEST) {
super.startActivityForResult(intent, requestCode);
return;
}
super.startActivityForResult(intent, requestCode, getActivityOptionsBundle());
}
@Override
public void startActivityForResult(Intent intent, int requestCode,
@androidx.annotation.Nullable Bundle options) {
if (!Utils.isPageTransitionEnabled(this) || requestCode == DEFAULT_REQUEST
|| options != null) {
super.startActivityForResult(intent, requestCode, options);
return;
}
super.startActivityForResult(intent, requestCode, getActivityOptionsBundle());
}
@Override
public void startActivityForResultAsUser(Intent intent, int requestCode,
UserHandle userHandle) {
if (!Utils.isPageTransitionEnabled(this) || requestCode == DEFAULT_REQUEST) {
super.startActivityForResultAsUser(intent, requestCode, userHandle);
return;
}
super.startActivityForResultAsUser(intent, requestCode, getActivityOptionsBundle(),
userHandle);
}
@Override
protected void onResume() {
super.onResume();
@@ -267,6 +332,12 @@ public class SettingsBaseActivity extends FragmentActivity {
}
}
private Bundle getActivityOptionsBundle() {
final Toolbar toolbar = findViewById(R.id.action_bar);
return ActivityOptions.makeSceneTransitionAnimation(this, toolbar,
"shared_element_view").toBundle();
}
public interface CategoryListener {
/**
* @param categories the changed categories that have to be refreshed, or null to force

View File

@@ -17,18 +17,22 @@
package com.android.settings.core;
import android.annotation.StringRes;
import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.UserHandle;
import android.text.TextUtils;
import android.widget.Toolbar;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
public class SubSettingLauncher {
@@ -183,7 +187,16 @@ public class SubSettingLauncher {
resultListener.getActivity().startActivityForResultAsUser(intent, requestCode, userHandle);
}
private void launchForResult(Fragment listener, Intent intent, int requestCode) {
@VisibleForTesting
void launchForResult(Fragment listener, Intent intent, int requestCode) {
if (Utils.isPageTransitionEnabled(mContext)) {
final Activity activity = listener.getActivity();
final Toolbar toolbar = activity.findViewById(R.id.action_bar);
final Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(activity, toolbar,
"shared_element_view").toBundle();
listener.startActivityForResult(intent, requestCode, bundle);
return;
}
listener.startActivityForResult(intent, requestCode);
}
@@ -192,6 +205,7 @@ public class SubSettingLauncher {
intent.replaceExtras(mLaunchRequest.extras);
}
}
/**
* Simple container that has information about how to launch a subsetting.
*/

View File

@@ -60,6 +60,7 @@ import com.android.settings.development.bluetooth.BluetoothSampleRateDialogPrefe
import com.android.settings.development.qstile.DevelopmentTiles;
import com.android.settings.development.storage.SharedDataPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.actionbar.SearchMenuController;
import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -174,6 +175,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
SearchMenuController.init(this);
if (Utils.isMonkeyRunning()) {
getActivity().finish();
return;

View File

@@ -40,6 +40,7 @@ import com.android.settingslib.core.lifecycle.events.OnDestroy;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.utils.StringUtil;
import java.time.Clock;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
@@ -256,6 +257,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
: mTrapezoidIndex;
if (mBatteryChartView != null) {
mBatteryChartView.setLevels(mBatteryHistoryLevels);
setTimestampLabel();
}
refreshUi(refreshIndex, /*isForce=*/ true);
}
@@ -525,6 +527,28 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
return true;
}
@VisibleForTesting
void setTimestampLabel() {
if (mBatteryChartView == null || mBatteryHistoryKeys == null) {
return;
}
long latestTimestamp =
mBatteryHistoryKeys[mBatteryHistoryKeys.length - 1];
// Uses the current time if we don't have history data.
if (latestTimestamp == 0) {
latestTimestamp = Clock.systemUTC().millis();
}
// Generates timestamp label for chart graph (every 8 hours).
final long timeSlotOffset = DateUtils.HOUR_IN_MILLIS * 8;
final String[] timestampLabels = new String[4];
for (int index = 0; index < timestampLabels.length; index++) {
timestampLabels[index] =
ConvertUtils.utcToLocalTimeHour(
latestTimestamp - (3 - index) * timeSlotOffset);
}
mBatteryChartView.setTimestamps(timestampLabels);
}
private static String utcToLocalTime(long[] timestamps) {
final StringBuilder builder = new StringBuilder();
for (int index = 0; index < timestamps.length; index++) {

View File

@@ -196,6 +196,11 @@ public final class ConvertUtils {
for (int index = 0; index < timeSlotSize; index++) {
final Long currentTimestamp =
Long.valueOf(batteryHistoryKeys[index * timestampStride]);
// Uses empty list if the timestamp is default value.
if (currentTimestamp == 0) {
resultMap.put(Integer.valueOf(index), new ArrayList<BatteryDiffEntry>());
continue;
}
final Long nextTimestamp =
Long.valueOf(batteryHistoryKeys[index * timestampStride + 1]);
final Long nextTwoTimestamp =

View File

@@ -18,11 +18,14 @@ package com.android.settings.homepage;
import android.animation.LayoutTransition;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.os.Bundle;
import android.util.FeatureFlagUtils;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toolbar;
@@ -33,11 +36,13 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.accounts.AvatarViewMixin;
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.transition.SettingsTransitionHelper;
public class SettingsHomepageActivity extends FragmentActivity {
@@ -64,6 +69,12 @@ public class SettingsHomepageActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
if (Utils.isPageTransitionEnabled(this)) {
// Enable Activity transitions
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
SettingsTransitionHelper.applyForwardTransition(this);
SettingsTransitionHelper.applyBackwardTransition(this);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_homepage_container);
@@ -101,6 +112,16 @@ public class SettingsHomepageActivity extends FragmentActivity {
.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
}
@Override
public void startActivity(Intent intent) {
if (Utils.isPageTransitionEnabled(this)) {
final Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(this).toBundle();
super.startActivity(intent, bundle);
return;
}
super.startActivity(intent);
}
private void showSuggestionFragment() {
final Class<? extends Fragment> fragment = FeatureFactory.getFactory(this)
.getSuggestionFeatureProvider(this).getContextualSuggestionFragment();

View File

@@ -24,7 +24,6 @@ import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
@@ -75,8 +74,79 @@ public class ProviderModelSliceHelper {
mTelephonyManager = context.getSystemService(TelephonyManager.class);
}
private static void log(String s) {
Log.d(TAG, s);
/**
* @return whether there is the carrier item in the slice.
*/
public boolean hasCarrier() {
if (isAirplaneModeEnabled()
|| mSubscriptionManager == null || mTelephonyManager == null
|| mSubscriptionManager.getDefaultDataSubscriptionId()
== mSubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return false;
}
return true;
}
/**
* @return whether the MobileData's is enabled.
*/
public boolean isMobileDataEnabled() {
return mTelephonyManager.isDataEnabled();
}
/**
* To check the carrier data status.
*
* @return whether the carrier data is active.
*/
public boolean isDataSimActive() {
return MobileNetworkUtils.activeNetworkIsCellular(mContext);
}
/**
* @return whether the ServiceState's data state is in-service.
*/
public boolean isDataStateInService() {
return mTelephonyManager.getDataState() == mTelephonyManager.DATA_CONNECTED;
}
/**
* @return whether the ServiceState's voice state is in-service.
*/
public boolean isVoiceStateInService() {
final ServiceState serviceState = mTelephonyManager.getServiceState();
return serviceState != null
&& serviceState.getState() == serviceState.STATE_IN_SERVICE;
}
/**
* To get the signal bar icon with level.
*
* @return The Drawable which is a signal bar icon with level.
*/
public Drawable getDrawableWithSignalStrength() {
final SignalStrength strength = mTelephonyManager.getSignalStrength();
int level = (strength == null) ? 0 : strength.getLevel();
int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
if (mSubscriptionManager != null && shouldInflateSignalStrength(
mSubscriptionManager.getDefaultDataSubscriptionId())) {
level += 1;
numLevels += 1;
}
return MobileNetworkUtils.getSignalStrengthIcon(mContext, level, numLevels,
NO_CELL_DATA_TYPE_ICON, false);
}
/**
* To update the telephony with subid.
*/
public void updateTelephony() {
if (mSubscriptionManager == null || mSubscriptionManager.getDefaultDataSubscriptionId()
== mSubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return;
}
mTelephonyManager = mTelephonyManager.createForSubscriptionId(
mSubscriptionManager.getDefaultDataSubscriptionId());
}
protected ListBuilder createListBuilder(Uri uri) {
@@ -97,19 +167,6 @@ public class ProviderModelSliceHelper {
return item.isPresent() ? item.get() : null;
}
/**
* @return whether there is the carrier item in the slice.
*/
public boolean hasCarrier() {
if (isAirplaneModeEnabled()
|| mSubscriptionManager == null || mTelephonyManager == null
|| mSubscriptionManager.getDefaultDataSubscriptionId()
== mSubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return false;
}
return true;
}
protected ListBuilder.RowBuilder createCarrierRow(String networkTypeDescription) {
final String title = getMobileTitle();
final String summary = getMobileSummary(networkTypeDescription);
@@ -142,6 +199,18 @@ public class ProviderModelSliceHelper {
ListBuilder.ICON_IMAGE, mContext.getText(R.string.summary_placeholder));
}
protected boolean isAirplaneModeEnabled() {
return WirelessUtils.isAirplaneModeOn(mContext);
}
protected SubscriptionManager getSubscriptionManager() {
return mSubscriptionManager;
}
private static void log(String s) {
Log.d(TAG, s);
}
private PendingIntent getPrimaryAction(String intentAction) {
final Intent intent = new Intent(intentAction)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -153,40 +222,6 @@ public class ProviderModelSliceHelper {
return SignalStrengthUtil.shouldInflateSignalStrength(mContext, subId);
}
protected boolean isAirplaneModeEnabled() {
return WirelessUtils.isAirplaneModeOn(mContext);
}
protected boolean isMobileDataEnabled() {
if (mTelephonyManager == null) {
return false;
}
return mTelephonyManager.isDataEnabled();
}
/**
* To check the carrier data status.
*
* @return whether the carrier data is active.
*/
public boolean isDataSimActive() {
return isNoCarrierData() ? false : MobileNetworkUtils.activeNetworkIsCellular(mContext);
}
protected boolean isNoCarrierData() {
if (mTelephonyManager == null) {
return false;
}
boolean mobileDataOnAndNoData = isMobileDataEnabled()
&& mTelephonyManager.getDataState() != mTelephonyManager.DATA_CONNECTED;
ServiceState serviceState = mTelephonyManager.getServiceState();
boolean mobileDataOffAndOutOfService = !isMobileDataEnabled() && serviceState != null
&& serviceState.getState() == serviceState.STATE_OUT_OF_SERVICE;
log("mobileDataOnAndNoData: " + mobileDataOnAndNoData
+ ",mobileDataOffAndOutOfService: " + mobileDataOffAndOutOfService);
return mobileDataOnAndNoData || mobileDataOffAndOutOfService;
}
@VisibleForTesting
Drawable getMobileDrawable(Drawable drawable) throws Throwable {
// set color and drawable
@@ -194,7 +229,7 @@ public class ProviderModelSliceHelper {
log("mTelephonyManager == null");
return drawable;
}
if (!isNoCarrierData()) {
if (isDataStateInService() || isVoiceStateInService()) {
Semaphore lock = new Semaphore(0);
AtomicReference<Drawable> shared = new AtomicReference<>();
ThreadUtils.postOnMainThread(() -> {
@@ -213,35 +248,18 @@ public class ProviderModelSliceHelper {
return drawable;
}
/**
* To get the signal bar icon with level.
*
* @return The Drawable which is a signal bar icon with level.
*/
public Drawable getDrawableWithSignalStrength() {
final SignalStrength strength = mTelephonyManager.getSignalStrength();
int level = (strength == null) ? 0 : strength.getLevel();
int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
if (mSubscriptionManager != null && shouldInflateSignalStrength(
mSubscriptionManager.getDefaultDataSubscriptionId())) {
level += 1;
numLevels += 1;
}
return MobileNetworkUtils.getSignalStrengthIcon(mContext, level, numLevels,
NO_CELL_DATA_TYPE_ICON, false);
}
private String getMobileSummary(String networkTypeDescription) {
final WifiManager wifiManager = mContext.getSystemService(WifiManager.class);
if (!isMobileDataEnabled()) {
return mContext.getString(R.string.mobile_data_off_summary);
}
if (!isDataStateInService()) {
return mContext.getString(R.string.mobile_data_no_connection);
}
String summary = networkTypeDescription;
if (isDataSimActive()) {
summary = mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.mobile_data_connection_active),
networkTypeDescription);
} else if (!isMobileDataEnabled()) {
summary = mContext.getString(R.string.mobile_data_off_summary);
} else if (!wifiManager.isWifiEnabled() && !isDataSimActive()) {
summary = mContext.getString(R.string.mobile_data_no_connection);
}
return summary;
}
@@ -260,26 +278,10 @@ public class ProviderModelSliceHelper {
return title;
}
protected SubscriptionManager getSubscriptionManager() {
return mSubscriptionManager;
}
private Set<String> getKeywords() {
final String keywords = mContext.getString(R.string.keywords_internet);
return Arrays.stream(TextUtils.split(keywords, ","))
.map(String::trim)
.collect(Collectors.toSet());
}
/**
* To update the telephony with subid.
*/
public void updateTelephony() {
if (mSubscriptionManager == null || mSubscriptionManager.getDefaultDataSubscriptionId()
== mSubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return;
}
mTelephonyManager = mTelephonyManager.createForSubscriptionId(
mSubscriptionManager.getDefaultDataSubscriptionId());
}
}

View File

@@ -257,15 +257,20 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
}
private CharSequence getMobilePreferenceSummary(int subId) {
TelephonyManager tm = mTelephonyManager.createForSubscriptionId(subId);
String result = mSubsPrefCtrlInjector.getNetworkType(
mContext, mConfig, mTelephonyDisplayInfo, subId);
if (!tm.isDataEnabled()) {
final TelephonyManager tmForSubId = mTelephonyManager.createForSubscriptionId(subId);
if (!tmForSubId.isDataEnabled()) {
return mContext.getString(R.string.mobile_data_off_summary);
}
if (!result.isEmpty() && mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext)) {
final boolean isDataInService = tmForSubId.getDataState()
== TelephonyManager.DATA_CONNECTED;
String result = mSubsPrefCtrlInjector.getNetworkType(
mContext, mConfig, mTelephonyDisplayInfo, subId);
if (mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext)) {
result = mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.mobile_data_connection_active), result);
} else if (!isDataInService) {
result = mContext.getString(R.string.mobile_data_no_connection);
}
return Html.fromHtml(result, Html.FROM_HTML_MODE_LEGACY);
}
@@ -274,31 +279,27 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
final TelephonyManager tmForSubId = mTelephonyManager.createForSubscriptionId(subId);
final SignalStrength strength = tmForSubId.getSignalStrength();
int level = (strength == null) ? 0 : strength.getLevel();
int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
if (shouldInflateSignalStrength(subId)) {
level += 1;
numLevels += 1;
}
final boolean isMobileDataOn = tmForSubId.isDataEnabled();
Drawable icon = mSubsPrefCtrlInjector.getIcon(mContext, level, numLevels, false);
final boolean isActiveCellularNetwork =
mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext);
final boolean isMobileDataAccessible = tmForSubId.getDataState()
== TelephonyManager.DATA_CONNECTED;
final ServiceState serviceState = tmForSubId.getServiceState();
final boolean isVoiceOutOfService = (serviceState == null)
? true
: (serviceState.getState() == ServiceState.STATE_OUT_OF_SERVICE);
Drawable icon = mSubsPrefCtrlInjector.getIcon(mContext, level, numLevels, false);
if (isActiveCellularNetwork) {
icon.setTint(Utils.getColorAccentDefaultColor(mContext));
return icon;
}
if ((isMobileDataOn && isMobileDataAccessible)
|| (!isMobileDataOn && !isVoiceOutOfService)) {
final boolean isDataInService = tmForSubId.getDataState()
== TelephonyManager.DATA_CONNECTED;
final ServiceState serviceState = tmForSubId.getServiceState();
final boolean isVoiceInService = (serviceState == null)
? false
: (serviceState.getState() == ServiceState.STATE_IN_SERVICE);
if (isDataInService || isVoiceInService) {
return icon;
}
@@ -579,7 +580,8 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
String iconKey = getIconKey(telephonyDisplayInfo);
int resId = mapIconSets(config).get(iconKey).dataContentDescription;
return resId != 0
? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId) : "";
? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId)
: "";
}
/**

View File

@@ -301,21 +301,37 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
}
final List<ScanResult> wifiList = mWifiManager.getScanResults();
if (wifiList != null && wifiList.size() == 0) {
if (wifiList != null && wifiList.size() != 0) {
return;
}
// Sub-Title:
// show non_carrier_network_unavailable
// - while Wi-Fi on + no Wi-Fi item
// - while Wi-Fi on + no Wi-Fi item + mobile data off
// show all_network_unavailable:
// - while Wi-Fi on + no Wi-Fi item + no carrier
// - while Wi-Fi on + no Wi-Fi item + no data capability
// - while Wi-Fi on + no Wi-Fi item + no carrier item
// - while Wi-Fi on + no Wi-Fi item + service is out of service
// - while Wi-Fi on + no Wi-Fi item + mobile data on + no carrier data.
log("No Wi-Fi item.");
mSubtitle = SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE;
if (!mProviderModelSliceHelper.hasCarrier()
|| !mProviderModelSliceHelper.isDataSimActive()) {
log("No carrier item or no carrier data.");
|| (!mProviderModelSliceHelper.isVoiceStateInService()
&& !mProviderModelSliceHelper.isDataStateInService())) {
log("no carrier or service is out of service.");
mSubtitle = SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE;
return;
}
if (!mProviderModelSliceHelper.isMobileDataEnabled()) {
log("mobile data off");
mSubtitle = SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE;
return;
}
if (!mProviderModelSliceHelper.isDataSimActive()) {
log("no carrier data.");
mSubtitle = SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE;
return;
}
mSubtitle = SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE;
}
private class NetworkProviderTelephonyCallback extends TelephonyCallback implements

View File

@@ -27,6 +27,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -172,7 +173,7 @@ public class UsbDefaultFragmentTest {
mFragment.onPause();
verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_RNDIS);
verify(mUsbBackend, times(2)).setDefaultUsbFunctions(UsbManager.FUNCTION_RNDIS);
assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_RNDIS);
}
@@ -184,7 +185,7 @@ public class UsbDefaultFragmentTest {
mFragment.onPause();
verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_NONE);
verify(mUsbBackend, times(2)).setDefaultUsbFunctions(UsbManager.FUNCTION_NONE);
assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_NONE);
}
@@ -196,7 +197,7 @@ public class UsbDefaultFragmentTest {
mFragment.onPause();
verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_MTP);
verify(mUsbBackend, times(2)).setDefaultUsbFunctions(UsbManager.FUNCTION_MTP);
assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_MTP);
}
@@ -208,7 +209,7 @@ public class UsbDefaultFragmentTest {
mFragment.onPause();
verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_PTP);
verify(mUsbBackend, times(2)).setDefaultUsbFunctions(UsbManager.FUNCTION_PTP);
assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_PTP);
}
@@ -220,7 +221,7 @@ public class UsbDefaultFragmentTest {
mFragment.onPause();
verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_MIDI);
verify(mUsbBackend, times(2)).setDefaultUsbFunctions(UsbManager.FUNCTION_MIDI);
assertThat(mFragment.mCurrentFunctions).isEqualTo(UsbManager.FUNCTION_MIDI);
}
@@ -250,6 +251,21 @@ public class UsbDefaultFragmentTest {
eq(mFragment.mOnStartTetheringCallback));
}
@Test
public void usbIsPluginAndUsbTetheringIsAlreadyStarted_startTetheringIsNotInvoked() {
mFragment.mIsStartTethering = true;
when(mUsbBackend.getDefaultUsbFunctions()).thenReturn(UsbManager.FUNCTION_RNDIS);
mFragment.mUsbConnectionListener.onUsbConnectionChanged(false /* connected */,
UsbManager.FUNCTION_RNDIS, POWER_ROLE_SINK, DATA_ROLE_DEVICE);
mFragment.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */,
UsbManager.FUNCTION_RNDIS, POWER_ROLE_SINK, DATA_ROLE_DEVICE);
verify(mTetheringManager, never()).startTethering(eq(TetheringManager.TETHERING_USB),
any(),
eq(mFragment.mOnStartTetheringCallback));
}
public static class TestFragment extends UsbDefaultFragment {
public final PreferenceScreen mScreen;

View File

@@ -28,12 +28,14 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.android.settings.SettingsActivity;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import org.junit.Before;
@@ -42,10 +44,12 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowUtils.class)
public class SubSettingLauncherTest {
@Mock
@@ -109,10 +113,13 @@ public class SubSettingLauncherTest {
@Test
public void launch_hasRequestListener_shouldStartActivityForResult() {
ShadowUtils.setIsPageTransitionEnabled(true);
final int requestCode = 123123;
when(mFragment.getActivity()).thenReturn(mActivity);
final SubSettingLauncher launcher = spy(new SubSettingLauncher(mContext));
doNothing().when(launcher).launchForResult(any(Fragment.class), any(Intent.class),
anyInt());
launcher.setTitleText("123")
.setDestination(SubSettingLauncherTest.class.getName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -120,7 +127,8 @@ public class SubSettingLauncherTest {
.setResultListener(mFragment, requestCode)
.launch();
verify(mFragment).startActivityForResult(any(Intent.class), eq(requestCode));
verify(launcher)
.launchForResult(eq(mFragment), any(Intent.class), eq(requestCode));
}
@Test

View File

@@ -81,10 +81,7 @@ public final class BatteryChartPreferenceControllerTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mBatteryChartPreferenceController =
new BatteryChartPreferenceController(
mContext, "app_list", /*lifecycle=*/ null,
mSettingsActivity, mFragment);
mBatteryChartPreferenceController = createController();
mBatteryChartPreferenceController.mPrefContext = mContext;
mBatteryChartPreferenceController.mAppListPrefGroup = mAppListGroup;
mBatteryChartPreferenceController.mBatteryChartView = mBatteryChartView;
@@ -572,6 +569,52 @@ public final class BatteryChartPreferenceControllerTest {
.isEqualTo("System usage for past 24 hr");
}
@Test
public void testSetTimestampLabel_nullBatteryHistoryKeys_ignore() {
mBatteryChartPreferenceController = createController();
mBatteryChartPreferenceController.mBatteryHistoryKeys = null;
mBatteryChartPreferenceController.mBatteryChartView =
spy(new BatteryChartView(mContext));
mBatteryChartPreferenceController.setTimestampLabel();
verify(mBatteryChartPreferenceController.mBatteryChartView, never())
.setTimestamps(any());
}
@Test
public void testSetTimestampLabel_setExpectedTimestampData() {
mBatteryChartPreferenceController = createController();
mBatteryChartPreferenceController.mBatteryChartView =
spy(new BatteryChartView(mContext));
setUpBatteryHistoryKeys();
// Generates the expected result.
final String[] expectedResults = new String[4];
final long timeSlotOffset = DateUtils.HOUR_IN_MILLIS * 8;
for (int index = 0; index < expectedResults.length; index++) {
expectedResults[index] =
ConvertUtils.utcToLocalTimeHour(
1619247636826L - (3 - index) * timeSlotOffset);
}
mBatteryChartPreferenceController.setTimestampLabel();
verify(mBatteryChartPreferenceController.mBatteryChartView)
.setTimestamps(expectedResults);
}
@Test
public void testSetTimestampLabel_withoutValidTimestamp_setExpectedTimestampData() {
mBatteryChartPreferenceController = createController();
mBatteryChartPreferenceController.mBatteryChartView =
spy(new BatteryChartView(mContext));
mBatteryChartPreferenceController.mBatteryHistoryKeys = new long[] {0L};
mBatteryChartPreferenceController.setTimestampLabel();
verify(mBatteryChartPreferenceController.mBatteryChartView)
.setTimestamps(any());
}
private static Map<Long, List<BatteryHistEntry>> createBatteryHistoryMap(int size) {
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
for (int index = 0; index < size; index++) {
@@ -598,4 +641,10 @@ public final class BatteryChartPreferenceControllerTest {
ConvertUtils.sSimpleDateFormatForHour
.setTimeZone(TimeZone.getTimeZone("GMT"));
}
private BatteryChartPreferenceController createController() {
return new BatteryChartPreferenceController(
mContext, "app_list", /*lifecycle=*/ null,
mSettingsActivity, mFragment);
}
}

View File

@@ -39,6 +39,7 @@ import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.testutils.shadow.ShadowUtils;
import org.junit.Before;
import org.junit.Test;
@@ -58,12 +59,13 @@ import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowUserManager.class,
SettingsHomepageActivityTest.ShadowSuggestionFeatureProviderImpl.class})
SettingsHomepageActivityTest.ShadowSuggestionFeatureProviderImpl.class, ShadowUtils.class})
public class SettingsHomepageActivityTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowUtils.setIsPageTransitionEnabled(false);
}
@Test

View File

@@ -47,6 +47,7 @@ public class ShadowUtils {
private static boolean sIsVoiceCapable;
private static ArraySet<String> sResultLinks = new ArraySet<>();
private static boolean sIsBatteryPresent;
private static boolean sIsPageTransitionEnabled;
@Implementation
protected static int enforceSameOwner(Context context, int userId) {
@@ -69,6 +70,7 @@ public class ShadowUtils {
sIsVoiceCapable = false;
sResultLinks = new ArraySet<>();
sIsBatteryPresent = true;
sIsPageTransitionEnabled = true;
}
public static void setIsDemoUser(boolean isDemoUser) {
@@ -166,4 +168,13 @@ public class ShadowUtils {
public static void setIsBatteryPresent(boolean isBatteryPresent) {
sIsBatteryPresent = isBatteryPresent;
}
@Implementation
protected static boolean isPageTransitionEnabled(Context context) {
return sIsPageTransitionEnabled;
}
public static void setIsPageTransitionEnabled(boolean isPageTransitionEnabled) {
sIsPageTransitionEnabled = isPageTransitionEnabled;
}
}

View File

@@ -218,38 +218,6 @@ public class ProviderModelSliceHelperTest {
assertThat(testRowBuild.getSubtitle()).isEqualTo(expectedSubtitle);
}
@Test
public void isNoCarrierData_mobileDataOnAndNoData_returnTrue() {
mockConnections(true, ServiceState.STATE_IN_SERVICE, "",
mTelephonyManager.DATA_DISCONNECTED, true);
assertThat(mProviderModelSliceHelper.isNoCarrierData()).isTrue();
}
@Test
public void isNoCarrierData_mobileDataOffAndOutOfService_returnTrue() {
mockConnections(false, ServiceState.STATE_OUT_OF_SERVICE, "",
mTelephonyManager.DATA_DISCONNECTED, true);
assertThat(mProviderModelSliceHelper.isNoCarrierData()).isTrue();
}
@Test
public void isNoCarrierData_mobileDataOnAndDataConnected_returnFalse() {
mockConnections(true, ServiceState.STATE_IN_SERVICE, "", mTelephonyManager.DATA_CONNECTED,
true);
assertThat(mProviderModelSliceHelper.isNoCarrierData()).isFalse();
}
@Test
public void isNoCarrierData_mobileDataOffAndVoiceIsInService_returnFalse() {
mockConnections(false, ServiceState.STATE_IN_SERVICE, "",
mTelephonyManager.DATA_DISCONNECTED, true);
assertThat(mProviderModelSliceHelper.isNoCarrierData()).isFalse();
}
@Test
public void getMobileDrawable_noCarrierData_getMobileDrawable() throws Throwable {
mockConnections(false, ServiceState.STATE_OUT_OF_SERVICE, "",

View File

@@ -542,6 +542,33 @@ public class SubscriptionsPreferenceControllerTest {
assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
}
@Test
@UiThreadTest
public void onTelephonyDisplayInfoChanged_providerAndHasMultiSimAndOutOfService_noConnection() {
final String noConnectionSummary =
ResourcesUtils.getResourcesString(mContext, "mobile_data_no_connection");
final CharSequence expectedSummary =
Html.fromHtml(noConnectionSummary, Html.FROM_HTML_MODE_LEGACY);
final String networkType = "LTE";
final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
final TelephonyDisplayInfo telephonyDisplayInfo =
new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
setupGetIconConditions(sub.get(0).getSubscriptionId(), false, true,
TelephonyManager.DATA_DISCONNECTED, ServiceState.STATE_OUT_OF_SERVICE);
doReturn(mock(MobileMappings.Config.class)).when(sInjector).getConfig(mContext);
doReturn(networkType)
.when(sInjector).getNetworkType(any(), any(), any(), anyInt());
mController.onResume();
mController.displayPreference(mPreferenceScreen);
mController.onTelephonyDisplayInfoChanged(telephonyDisplayInfo);
assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
}
@Test
@UiThreadTest
public void onAirplaneModeChanged_providerAndHasSim_noPreference() {

View File

@@ -129,7 +129,7 @@ public class InternetConnectivityPanelTest {
@Test
public void getSubTitle_apmOffWifiOnNoWifiListHasCarrierData_NonCarrierNetworkUnavailable() {
List wifiList = new ArrayList<ScanResult>();
mockCondition(false, true, true, true, wifiList);
mockCondition(false, true, true, true, true, true, wifiList);
mPanel.updatePanelTitle();
@@ -137,9 +137,29 @@ public class InternetConnectivityPanelTest {
}
@Test
public void getSubTitle_apmOffWifiOnNoWifiListNoCarrierData_AllNetworkUnavailable() {
public void getSubTitle_apmOffWifiOnNoWifiListNoCarrierItem_AllNetworkUnavailable() {
List wifiList = new ArrayList<ScanResult>();
mockCondition(false, true, false, true, wifiList);
mockCondition(false, false, false, false, false, true, wifiList);
mPanel.updatePanelTitle();
assertThat(mPanel.getSubTitle()).isEqualTo(SUBTITLE_ALL_NETWORK_UNAVAILABLE);
}
@Test
public void getSubTitle_apmOffWifiOnNoWifiListNoDataSimActive_AllNetworkUnavailable() {
List wifiList = new ArrayList<ScanResult>();
mockCondition(false, true, false, true, true, true, wifiList);
mPanel.updatePanelTitle();
assertThat(mPanel.getSubTitle()).isEqualTo(SUBTITLE_ALL_NETWORK_UNAVAILABLE);
}
@Test
public void getSubTitle_apmOffWifiOnNoWifiListNoService_AllNetworkUnavailable() {
List wifiList = new ArrayList<ScanResult>();
mockCondition(false, true, false, true, false, true, wifiList);
mPanel.updatePanelTitle();
@@ -151,7 +171,7 @@ public class InternetConnectivityPanelTest {
List wifiList = new ArrayList<ScanResult>();
wifiList.add(new ScanResult());
wifiList.add(new ScanResult());
mockCondition(false, true, false, true, wifiList);
mockCondition(false, true, false, true, true, true, wifiList);
mPanel.updatePanelTitle();
@@ -184,7 +204,7 @@ public class InternetConnectivityPanelTest {
@Test
public void getSlices_providerModelDisabled_containsNecessarySlices() {
mPanel.mIsProviderModelEnabled = false;
final List<Uri> uris = mPanel.getSlices();
List<Uri> uris = mPanel.getSlices();
assertThat(uris).containsExactly(
AirplaneModePreferenceController.SLICE_URI,
@@ -194,7 +214,7 @@ public class InternetConnectivityPanelTest {
@Test
public void getSlices_providerModelEnabled_containsNecessarySlices() {
final List<Uri> uris = mPanel.getSlices();
List<Uri> uris = mPanel.getSlices();
assertThat(uris).containsExactly(
CustomSliceRegistry.PROVIDER_MODEL_SLICE_URI,
@@ -291,10 +311,14 @@ public class InternetConnectivityPanelTest {
}
private void mockCondition(boolean airplaneMode, boolean hasCarrier,
boolean isDataSimActive, boolean isWifiEnabled, List<ScanResult> wifiItems) {
boolean isDataSimActive, boolean isMobileDataEnabled, boolean isServiceInService,
boolean isWifiEnabled, List<ScanResult> wifiItems) {
doReturn(airplaneMode).when(mInternetUpdater).isAirplaneModeOn();
when(mProviderModelSliceHelper.hasCarrier()).thenReturn(hasCarrier);
when(mProviderModelSliceHelper.isDataSimActive()).thenReturn(isDataSimActive);
when(mProviderModelSliceHelper.isMobileDataEnabled()).thenReturn(isMobileDataEnabled);
when(mProviderModelSliceHelper.isDataStateInService()).thenReturn(isServiceInService);
when(mProviderModelSliceHelper.isVoiceStateInService()).thenReturn(isServiceInService);
doReturn(isWifiEnabled).when(mInternetUpdater).isWifiEnabled();
doReturn(wifiItems).when(mWifiManager).getScanResults();
}