Snap for 5012867 from f66f042009 to qt-release
Change-Id: I29ec3bc2666d4feedec38f3af6929b2af08ba8f2
This commit is contained in:
@@ -1128,12 +1128,12 @@
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<activity android:name=".applications.InstalledAppOpenByDefaultPage"
|
||||
<activity android:name=".applications.InstalledAppOpenByDefaultActivity"
|
||||
android:label="@string/application_info_label"
|
||||
android:permission="android.permission.OPEN_APPLICATION_DETAILS_OPEN_BY_DEFAULT_PAGE"
|
||||
android:permission="android.permission.OPEN_APP_OPEN_BY_DEFAULT_SETTINGS"
|
||||
android:exported="true">
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.settings.APPLICATION_DETAILS_SETTINGS_OPEN_BY_DEFAULT_PAGE" />
|
||||
<action android:name="com.android.settings.APP_OPEN_BY_DEFAULT_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="package" />
|
||||
</intent-filter>
|
||||
|
||||
@@ -8948,8 +8948,6 @@
|
||||
<string name="disabled_by_policy_title_camera">Camera not allowed</string>
|
||||
<!-- Title for dialog displayed to tell user that screenshots are disabled by an admin [CHAR LIMIT=50] -->
|
||||
<string name="disabled_by_policy_title_screen_capture">Screenshot not allowed</string>
|
||||
<!-- Title for dialog displayed to tell user that turning off backups is disallowed by an admin [CHAR LIMIT=50] -->
|
||||
<string name="disabled_by_policy_title_turn_off_backups">Can’t turn off backups</string>
|
||||
<!-- Title for dialog displayed to tell user that the app was suspended by an admin [CHAR LIMIT=50] -->
|
||||
<string name="disabled_by_policy_title_suspend_packages">Can’t open this app</string>
|
||||
<!-- Shown when the user tries to change a settings locked by an admin [CHAR LIMIT=200] -->
|
||||
@@ -9749,8 +9747,6 @@
|
||||
<item quantity="one"><xliff:g id="count">%d</xliff:g> attempt</item>
|
||||
<item quantity="other"><xliff:g id="count">%d</xliff:g> attempts</item>
|
||||
</plurals>
|
||||
<!-- List item in a work device's settings. This text lets the user know that their IT administrator requires their device's data to be backed up. The user can't change this setting. [CHAR LIMIT=NONE] -->
|
||||
<string name="enterprise_privacy_backups_enabled">This device\'s data is being backed up</string>
|
||||
<!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
|
||||
<string name="do_disclosure_generic">This device is managed by your organization.</string>
|
||||
<!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
|
||||
|
||||
@@ -83,9 +83,6 @@
|
||||
<Preference android:key="ca_certs_managed_profile"
|
||||
android:title="@string/enterprise_privacy_ca_certs_work"
|
||||
android:selectable="false"/>
|
||||
<Preference android:key="backups_enabled"
|
||||
android:title="@string/enterprise_privacy_backups_enabled"
|
||||
android:selectable="false"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:key="device_access_category"
|
||||
|
||||
@@ -20,7 +20,7 @@ import android.content.Intent;
|
||||
|
||||
import com.android.settings.SettingsActivity;
|
||||
|
||||
public class InstalledAppOpenByDefaultPage extends SettingsActivity {
|
||||
public class InstalledAppOpenByDefaultActivity extends SettingsActivity {
|
||||
|
||||
@Override
|
||||
public Intent getIntent() {
|
||||
@@ -111,7 +111,7 @@ public class DefaultBrowserPreferenceController extends DefaultAppPreferenceCont
|
||||
final List<ResolveInfo> candidates = new ArrayList<>();
|
||||
// Resolve that intent and check that the handleAllWebDataURI boolean is set
|
||||
final List<ResolveInfo> list = packageManager.queryIntentActivitiesAsUser(
|
||||
BROWSE_PROBE, PackageManager.MATCH_ALL, userId);
|
||||
BROWSE_PROBE, 0 /* flags */, userId);
|
||||
if (list != null) {
|
||||
final Set<String> addedPackages = new ArraySet<>();
|
||||
for (ResolveInfo info : list) {
|
||||
@@ -181,13 +181,12 @@ public class DefaultBrowserPreferenceController extends DefaultAppPreferenceCont
|
||||
* Whether or not the pkg is the default browser
|
||||
*/
|
||||
public boolean isBrowserDefault(String pkg, int userId) {
|
||||
String defaultPackage = mPackageManager.getDefaultBrowserPackageNameAsUser(userId);
|
||||
final String defaultPackage = mPackageManager.getDefaultBrowserPackageNameAsUser(userId);
|
||||
if (defaultPackage != null) {
|
||||
return defaultPackage.equals(pkg);
|
||||
}
|
||||
|
||||
final List<ResolveInfo> list = mPackageManager.queryIntentActivitiesAsUser(BROWSE_PROBE,
|
||||
PackageManager.MATCH_ALL, userId);
|
||||
final List<ResolveInfo> list = getCandidates(mPackageManager, userId);
|
||||
// There is only 1 app, it must be the default browser.
|
||||
return list != null && list.size() == 1;
|
||||
}
|
||||
|
||||
@@ -137,9 +137,6 @@ public class ActionDisabledByAdminDialogHelper {
|
||||
case DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE:
|
||||
titleView.setText(R.string.disabled_by_policy_title_screen_capture);
|
||||
break;
|
||||
case DevicePolicyManager.POLICY_MANDATORY_BACKUPS:
|
||||
titleView.setText(R.string.disabled_by_policy_title_turn_off_backups);
|
||||
break;
|
||||
case DevicePolicyManager.POLICY_SUSPEND_PACKAGES:
|
||||
titleView.setText(R.string.disabled_by_policy_title_suspend_packages);
|
||||
break;
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.enterprise;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
public class BackupsEnabledPreferenceController extends BasePreferenceController {
|
||||
|
||||
private static final String KEY_BACKUPS_ENABLED = "backups_enabled";
|
||||
private final EnterprisePrivacyFeatureProvider mFeatureProvider;
|
||||
|
||||
public BackupsEnabledPreferenceController(Context context) {
|
||||
super(context, KEY_BACKUPS_ENABLED);
|
||||
mFeatureProvider = FeatureFactory.getFactory(context)
|
||||
.getEnterprisePrivacyFeatureProvider(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return mFeatureProvider.areBackupsMandatory() ? AVAILABLE : DISABLED_FOR_USER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,9 +124,4 @@ public interface EnterprisePrivacyFeatureProvider {
|
||||
* profile (if any).
|
||||
*/
|
||||
int getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile();
|
||||
|
||||
/*
|
||||
* Returns whether backups are mandatory.
|
||||
*/
|
||||
boolean areBackupsMandatory();
|
||||
}
|
||||
|
||||
@@ -234,11 +234,6 @@ public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFe
|
||||
return activeAdmins;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areBackupsMandatory() {
|
||||
return null != mDpm.getMandatoryBackupTransport();
|
||||
}
|
||||
|
||||
protected static class EnterprisePrivacySpan extends ClickableSpan {
|
||||
private final Context mContext;
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ public class EnterprisePrivacySettings extends DashboardFragment {
|
||||
exposureChangesCategoryControllers.add(new CaCertsCurrentUserPreferenceController(context));
|
||||
exposureChangesCategoryControllers.add(new CaCertsManagedProfilePreferenceController(
|
||||
context));
|
||||
exposureChangesCategoryControllers.add(new BackupsEnabledPreferenceController(context));
|
||||
controllers.addAll(exposureChangesCategoryControllers);
|
||||
controllers.add(new PreferenceCategoryController(context, "exposure_changes_category")
|
||||
.setChildren(exposureChangesCategoryControllers));
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.android.settings.homepage;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settingslib.utils.AsyncLoaderCompat;
|
||||
|
||||
@@ -45,28 +45,22 @@ public class CardContentLoader extends AsyncLoaderCompat<List<ContextualCard>> {
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
@Override
|
||||
public List<ContextualCard> loadInBackground() {
|
||||
List<ContextualCard> result;
|
||||
try (Cursor cursor = CardDatabaseHelper.getInstance(mContext).getAllContextualCards()) {
|
||||
final List<ContextualCard> result = new ArrayList<>();
|
||||
try (Cursor cursor = CardDatabaseHelper.getInstance(mContext).getContextualCards()) {
|
||||
if (cursor.getCount() == 0) {
|
||||
//TODO(b/113372471): Load Default static cards and return 3 static cards
|
||||
return new ArrayList<>();
|
||||
return result;
|
||||
}
|
||||
result = buildContextualCardList(cursor);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<ContextualCard> buildContextualCardList(Cursor cursor) {
|
||||
final List<ContextualCard> result = new ArrayList<>();
|
||||
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
||||
final ContextualCard card = new ContextualCard(cursor);
|
||||
if (card.isCustomCard()) {
|
||||
//TODO(b/114688391): Load and generate custom card,then add into list
|
||||
} else {
|
||||
result.add(card);
|
||||
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
||||
final ContextualCard card = new ContextualCard(cursor);
|
||||
if (card.isCustomCard()) {
|
||||
//TODO(b/114688391): Load and generate custom card,then add into list
|
||||
} else {
|
||||
result.add(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -192,7 +192,7 @@ public class CardDatabaseHelper extends SQLiteOpenHelper {
|
||||
return sCardDatabaseHelper;
|
||||
}
|
||||
|
||||
Cursor getAllContextualCards() {
|
||||
Cursor getContextualCards() {
|
||||
final SQLiteDatabase db = this.getReadableDatabase();
|
||||
Cursor cursor = db.query(CARD_TABLE, null /* columns */, null /* selection */,
|
||||
null /* selectionArgs */, null /* groupBy */, null /* having */,
|
||||
|
||||
@@ -33,10 +33,10 @@ public class ContextualCard {
|
||||
/**
|
||||
* Flags indicating the type of the ContextualCard.
|
||||
*/
|
||||
@IntDef({CardType.INVALID, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
|
||||
@IntDef({CardType.DEFAULT, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface CardType {
|
||||
int INVALID = -1;
|
||||
int DEFAULT = 0;
|
||||
int SLICE = 1;
|
||||
int SUGGESTION = 2;
|
||||
int CONDITIONAL = 3;
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.settings.homepage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Data controller for {@link ContextualCard}.
|
||||
*/
|
||||
@@ -26,12 +24,6 @@ public interface ContextualCardController {
|
||||
@ContextualCard.CardType
|
||||
int getCardType();
|
||||
|
||||
/**
|
||||
* When data is updated or changed, the new data should be passed to ContextualCardManager for list
|
||||
* updating.
|
||||
*/
|
||||
void onDataUpdated(List<ContextualCard> cardList);
|
||||
|
||||
void onPrimaryClick(ContextualCard card);
|
||||
|
||||
void onActionClick(ContextualCard card);
|
||||
|
||||
@@ -18,8 +18,12 @@ package com.android.settings.homepage;
|
||||
|
||||
import static com.android.settings.homepage.CardContentLoader.CARD_CONTENT_LOADER_ID;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -32,6 +36,9 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* This is a centralized manager of multiple {@link ContextualCardController}.
|
||||
@@ -57,18 +64,23 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade
|
||||
private final ControllerRendererPool mControllerRendererPool;
|
||||
private final Lifecycle mLifecycle;
|
||||
private final List<ContextualCard> mContextualCards;
|
||||
private final List<LifecycleObserver> mLifecycleObservers;
|
||||
|
||||
private ContextualCardUpdateListener mListener;
|
||||
|
||||
|
||||
public ContextualCardManager(Context context, Lifecycle lifecycle) {
|
||||
public ContextualCardManager(Context context, @NonNull Lifecycle lifecycle) {
|
||||
mContext = context;
|
||||
mLifecycle = lifecycle;
|
||||
mContextualCards = new ArrayList<>();
|
||||
mLifecycleObservers = new ArrayList<>();
|
||||
mControllerRendererPool = new ControllerRendererPool();
|
||||
//for data provided by Settings
|
||||
for (int cardType : SETTINGS_CARDS) {
|
||||
setupController(cardType);
|
||||
}
|
||||
}
|
||||
|
||||
void startCardContentLoading(PersonalSettingsFragment fragment) {
|
||||
void loadContextualCards(PersonalSettingsFragment fragment) {
|
||||
final CardContentLoaderCallbacks cardContentLoaderCallbacks =
|
||||
new CardContentLoaderCallbacks(mContext);
|
||||
cardContentLoaderCallbacks.setListener(this);
|
||||
@@ -77,71 +89,64 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade
|
||||
}
|
||||
|
||||
private void loadCardControllers() {
|
||||
if (mContextualCards != null) {
|
||||
for (ContextualCard card : mContextualCards) {
|
||||
setupController(card.getCardType());
|
||||
}
|
||||
}
|
||||
|
||||
//for data provided by Settings
|
||||
for (int cardType : SETTINGS_CARDS) {
|
||||
setupController(cardType);
|
||||
for (ContextualCard card : mContextualCards) {
|
||||
setupController(card.getCardType());
|
||||
}
|
||||
}
|
||||
|
||||
private void setupController(int cardType) {
|
||||
final ContextualCardController controller = mControllerRendererPool.getController(mContext,
|
||||
cardType);
|
||||
if (controller != null) {
|
||||
controller.setCardUpdateListener(this);
|
||||
if (controller instanceof LifecycleObserver) {
|
||||
if (mLifecycle != null) {
|
||||
mLifecycle.addObserver((LifecycleObserver) controller);
|
||||
}
|
||||
}
|
||||
if (controller == null) {
|
||||
Log.w(TAG, "Cannot find ContextualCardController for type " + cardType);
|
||||
return;
|
||||
}
|
||||
controller.setCardUpdateListener(this);
|
||||
if (controller instanceof LifecycleObserver && !mLifecycleObservers.contains(controller)) {
|
||||
mLifecycleObservers.add((LifecycleObserver) controller);
|
||||
mLifecycle.addObserver((LifecycleObserver) controller);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO(b/111822376): implement sorting mechanism.
|
||||
private void sortCards() {
|
||||
private void sortCards(List<ContextualCard> cards) {
|
||||
//take mContextualCards as the source and do the ranking based on the rule.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContextualCardUpdated(int cardType, List<ContextualCard> updateList) {
|
||||
public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> updateList) {
|
||||
//TODO(b/112245748): Should implement a DiffCallback.
|
||||
//Keep the old list for comparison.
|
||||
final List<ContextualCard> prevCards = mContextualCards;
|
||||
|
||||
//Remove the existing data that matches the certain cardType so as to insert the new data.
|
||||
for (int i = mContextualCards.size() - 1; i >= 0; i--) {
|
||||
if (mContextualCards.get(i).getCardType() == cardType) {
|
||||
mContextualCards.remove(i);
|
||||
}
|
||||
}
|
||||
final Set<Integer> cardTypes = updateList.keySet();
|
||||
//Remove the existing data that matches the certain cardType before inserting new data.
|
||||
final List<ContextualCard> cardsToKeep = mContextualCards
|
||||
.stream()
|
||||
.filter(card -> !cardTypes.contains(card.getCardType()))
|
||||
.collect(Collectors.toList());
|
||||
final List<ContextualCard> allCards = new ArrayList<>();
|
||||
allCards.addAll(cardsToKeep);
|
||||
allCards.addAll(
|
||||
updateList.values().stream().flatMap(List::stream).collect(Collectors.toList()));
|
||||
|
||||
//Append the new data
|
||||
mContextualCards.addAll(updateList);
|
||||
sortCards(allCards);
|
||||
//replace with the new data
|
||||
mContextualCards.clear();
|
||||
mContextualCards.addAll(allCards);
|
||||
|
||||
sortCards();
|
||||
loadCardControllers();
|
||||
|
||||
if (mListener != null) {
|
||||
mListener.onContextualCardUpdated(ContextualCard.CardType.INVALID, mContextualCards);
|
||||
final Map<Integer, List<ContextualCard>> cardsToUpdate = new ArrayMap<>();
|
||||
cardsToUpdate.put(ContextualCard.CardType.DEFAULT, mContextualCards);
|
||||
mListener.onContextualCardUpdated(cardsToUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishCardLoading(List<ContextualCard> contextualCards) {
|
||||
mContextualCards.clear();
|
||||
if (contextualCards != null) {
|
||||
mContextualCards.addAll(contextualCards);
|
||||
}
|
||||
|
||||
//Force card sorting here in case CardControllers of custom view have nothing to update
|
||||
// for the first launch.
|
||||
sortCards();
|
||||
|
||||
loadCardControllers();
|
||||
public void onFinishCardLoading(List<ContextualCard> cards) {
|
||||
onContextualCardUpdated(cards.stream().collect(groupingBy(ContextualCard::getCardType)));
|
||||
}
|
||||
|
||||
void setListener(ContextualCardUpdateListener listener) {
|
||||
@@ -152,7 +157,6 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade
|
||||
return mControllerRendererPool;
|
||||
}
|
||||
|
||||
|
||||
static class CardContentLoaderCallbacks implements
|
||||
LoaderManager.LoaderCallbacks<List<ContextualCard>> {
|
||||
|
||||
|
||||
@@ -31,15 +31,15 @@ public interface ContextualCardRenderer {
|
||||
int getViewType();
|
||||
|
||||
/**
|
||||
* When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder(ViewGroup,
|
||||
* int)}, this method will be called to retrieve the corresponding
|
||||
* When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder},
|
||||
* this method will be called to retrieve the corresponding
|
||||
* {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}.
|
||||
*/
|
||||
RecyclerView.ViewHolder createViewHolder(View view);
|
||||
|
||||
/**
|
||||
* When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onBindViewHolder(RecyclerView
|
||||
* .ViewHolder, int)}, this method will be called to bind data to the
|
||||
* When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onBindViewHolder},
|
||||
* this method will be called to bind data to the
|
||||
* {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}.
|
||||
*/
|
||||
void bindView(RecyclerView.ViewHolder holder, ContextualCard card);
|
||||
|
||||
@@ -17,15 +17,19 @@
|
||||
package com.android.settings.homepage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* When {@link ContextualCardController} detects changes, it will notify the listeners registered.
|
||||
* In our case, {@link ContextualCardManager} gets noticed.
|
||||
*
|
||||
* After the list of {@link ContextualCard} gets updated in{@link ContextualCardManager},
|
||||
* {@link ContextualCardManager} will notify the listeners registered, {@link
|
||||
* ContextualCardsAdapter} in this case.
|
||||
*/
|
||||
public interface ContextualCardUpdateListener {
|
||||
void onContextualCardUpdated(int cardType, List<ContextualCard> updateList);
|
||||
|
||||
/**
|
||||
* Called when a set of cards are updated.
|
||||
*
|
||||
* @param cards A map of updates grouped by {@link ContextualCard.CardType}. Values can be
|
||||
* null, which means all cards from corresponding {@link
|
||||
* ContextualCard.CardType} are removed.
|
||||
*/
|
||||
void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards);
|
||||
}
|
||||
@@ -26,9 +26,10 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements
|
||||
ContextualCardUpdateListener {
|
||||
public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||
implements ContextualCardUpdateListener {
|
||||
static final int SPAN_COUNT = 2;
|
||||
|
||||
private static final String TAG = "ContextualCardsAdapter";
|
||||
@@ -101,7 +102,8 @@ public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.Vi
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContextualCardUpdated(int cardType, List<ContextualCard> contextualCards) {
|
||||
public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards) {
|
||||
final List<ContextualCard> contextualCards = cards.get(ContextualCard.CardType.DEFAULT);
|
||||
//TODO(b/112245748): Should implement a DiffCallback so we can use notifyItemChanged()
|
||||
// instead.
|
||||
if (contextualCards == null) {
|
||||
|
||||
@@ -43,7 +43,7 @@ public class PersonalSettingsFragment extends InstrumentedFragment {
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mContextualCardManager = new ContextualCardManager(getContext(), getSettingsLifecycle());
|
||||
mContextualCardManager.startCardContentLoading(this);
|
||||
mContextualCardManager.loadContextualCards(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.homepage.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import com.android.settings.homepage.ContextualCard;
|
||||
import com.android.settings.homepage.ContextualCardController;
|
||||
@@ -27,6 +28,7 @@ import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This controller triggers the loading of conditional cards and monitors state changes to
|
||||
@@ -56,11 +58,6 @@ public class ConditionContextualCardController implements ContextualCardControll
|
||||
return ContextualCard.CardType.CONDITIONAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataUpdated(List<ContextualCard> cardList) {
|
||||
mListener.onContextualCardUpdated(getCardType(), cardList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
mConditionManager.startMonitoringStateChange();
|
||||
@@ -96,7 +93,6 @@ public class ConditionContextualCardController implements ContextualCardControll
|
||||
.setActionText(condition.getActionText())
|
||||
.setName(mContext.getPackageName() + "/"
|
||||
+ condition.getTitle().toString())
|
||||
.setCardType(ContextualCard.CardType.CONDITIONAL)
|
||||
.setTitleText(condition.getTitle().toString())
|
||||
.setSummaryText(condition.getSummary().toString())
|
||||
.setIconDrawable(condition.getIcon())
|
||||
@@ -106,7 +102,9 @@ public class ConditionContextualCardController implements ContextualCardControll
|
||||
}
|
||||
|
||||
if (mListener != null) {
|
||||
onDataUpdated(conditionCards);
|
||||
final Map<Integer, List<ContextualCard>> conditionalCards = new ArrayMap<>();
|
||||
conditionalCards.put(ContextualCard.CardType.CONDITIONAL, conditionCards);
|
||||
mListener.onContextualCardUpdated(conditionalCards);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.homepage.conditional;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.homepage.ContextualCard;
|
||||
|
||||
/**
|
||||
@@ -38,6 +40,11 @@ public class ConditionalContextualCard extends ContextualCard {
|
||||
mActionText = builder.mActionText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCardType() {
|
||||
return CardType.CONDITIONAL;
|
||||
}
|
||||
|
||||
public long getConditionId() {
|
||||
return mConditionId;
|
||||
}
|
||||
@@ -50,7 +57,7 @@ public class ConditionalContextualCard extends ContextualCard {
|
||||
return mActionText;
|
||||
}
|
||||
|
||||
static class Builder extends ContextualCard.Builder {
|
||||
public static class Builder extends ContextualCard.Builder {
|
||||
|
||||
private long mConditionId;
|
||||
private int mMetricsConstant;
|
||||
@@ -71,6 +78,12 @@ public class ConditionalContextualCard extends ContextualCard {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder setCardType(int cardType) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot change card type for " + getClass().getName());
|
||||
}
|
||||
|
||||
public ConditionalContextualCard build() {
|
||||
return new ConditionalContextualCard(this);
|
||||
}
|
||||
|
||||
@@ -78,6 +78,12 @@ public class NotificationBackend {
|
||||
return row;
|
||||
}
|
||||
|
||||
public boolean isBlockable(Context context, ApplicationInfo info) {
|
||||
final boolean blocked = getNotificationsBanned(info.packageName, info.uid);
|
||||
final boolean systemApp = isSystemApp(context, info);
|
||||
return !systemApp || (systemApp && blocked);
|
||||
}
|
||||
|
||||
public AppRow loadAppRow(Context context, PackageManager pm, PackageInfo app) {
|
||||
final AppRow row = loadAppRow(context, pm, app.applicationInfo);
|
||||
recordCanBeBlocked(context, pm, app, row);
|
||||
|
||||
@@ -82,17 +82,6 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC
|
||||
private Preference mSeeAllPref;
|
||||
private Preference mDivider;
|
||||
|
||||
static {
|
||||
SKIP_SYSTEM_PACKAGES.addAll(Arrays.asList(
|
||||
"android",
|
||||
"com.android.phone",
|
||||
"com.android.settings",
|
||||
"com.android.systemui",
|
||||
"com.android.providers.calendar",
|
||||
"com.android.providers.media"
|
||||
));
|
||||
}
|
||||
|
||||
public RecentNotifyingAppsPreferenceController(Context context, NotificationBackend backend,
|
||||
Application app, Fragment host) {
|
||||
this(context, backend, app == null ? null : ApplicationsState.getInstance(app), host);
|
||||
@@ -226,6 +215,7 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC
|
||||
.setSourceMetricsCategory(
|
||||
MetricsProto.MetricsEvent.MANAGE_APPLICATIONS_NOTIFICATIONS)
|
||||
.toIntent());
|
||||
pref.setEnabled(mNotificationBackend.isBlockable(mContext, appEntry.info));
|
||||
pref.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean blocked = !(Boolean) newValue;
|
||||
mNotificationBackend.setNotificationsEnabledForPackage(
|
||||
@@ -272,10 +262,6 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC
|
||||
* Whether or not the app should be included in recent list.
|
||||
*/
|
||||
private boolean shouldIncludePkgInRecents(String pkgName) {
|
||||
if (SKIP_SYSTEM_PACKAGES.contains(pkgName)) {
|
||||
Log.d(TAG, "System package, skipping " + pkgName);
|
||||
return false;
|
||||
}
|
||||
final Intent launchIntent = new Intent().addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
.setPackage(pkgName);
|
||||
|
||||
|
||||
@@ -465,8 +465,7 @@ public class WifiConfigController implements TextWatcher,
|
||||
} else {
|
||||
enabled = ipAndProxyFieldsAreValid();
|
||||
}
|
||||
if (mEapCaCertSpinner != null
|
||||
&& mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) {
|
||||
if (mAccessPointSecurity == AccessPoint.SECURITY_EAP) {
|
||||
String caCertSelection = (String) mEapCaCertSpinner.getSelectedItem();
|
||||
if (caCertSelection.equals(mUnspecifiedCertString)) {
|
||||
// Disallow submit if the user has not selected a CA certificate for an EAP network
|
||||
@@ -482,10 +481,8 @@ public class WifiConfigController implements TextWatcher,
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
if (mEapUserCertSpinner != null
|
||||
&& mView.findViewById(R.id.l_user_cert).getVisibility() != View.GONE
|
||||
&& ((String) mEapUserCertSpinner.getSelectedItem())
|
||||
.equals(mUnspecifiedCertString)) {
|
||||
if (mAccessPointSecurity == AccessPoint.SECURITY_EAP
|
||||
&& mEapUserCertSpinner.getSelectedItem().equals(mUnspecifiedCertString)) {
|
||||
// Disallow submit if the user has not selected a user certificate for an EAP network
|
||||
// configuration.
|
||||
enabled = false;
|
||||
|
||||
@@ -18,9 +18,9 @@ package com.android.settings.applications.defaultapps;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -133,8 +133,11 @@ public class DefaultBrowserPreferenceControllerTest {
|
||||
@Test
|
||||
public void isBrowserDefault_onlyApp_shouldReturnTrue() {
|
||||
when(mPackageManager.getDefaultBrowserPackageNameAsUser(anyInt())).thenReturn(null);
|
||||
final List<ResolveInfo> resolveInfos = new ArrayList<>();
|
||||
final String PACKAGE_ONE = "pkg";
|
||||
resolveInfos.add(createResolveInfo(PACKAGE_ONE));
|
||||
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
|
||||
.thenReturn(Collections.singletonList(new ResolveInfo()));
|
||||
.thenReturn(resolveInfos);
|
||||
|
||||
assertThat(mController.isBrowserDefault("pkg", 0)).isTrue();
|
||||
}
|
||||
@@ -161,6 +164,15 @@ public class DefaultBrowserPreferenceControllerTest {
|
||||
assertThat(defaultBrowserInfo.size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCandidates_shouldQueryActivityWithFlagsEquals0() {
|
||||
|
||||
mController.getCandidates(mPackageManager, 0 /* userId */);
|
||||
|
||||
verify(mPackageManager).queryIntentActivitiesAsUser(
|
||||
any(Intent.class), eq(0) /* flags */, eq(0) /* userId */);
|
||||
}
|
||||
|
||||
private ResolveInfo createResolveInfo(String packageName) {
|
||||
final ResolveInfo info = new ResolveInfo();
|
||||
info.handleAllWebDataURI = true;
|
||||
|
||||
@@ -124,10 +124,6 @@ public class ActionDisabledByAdminDialogHelperTest {
|
||||
assertEquals(Shadows.shadowOf(textView).innerText(),
|
||||
mActivity.getString(R.string.disabled_by_policy_title_screen_capture));
|
||||
|
||||
mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_MANDATORY_BACKUPS);
|
||||
assertEquals(Shadows.shadowOf(textView).innerText(),
|
||||
mActivity.getString(R.string.disabled_by_policy_title_turn_off_backups));
|
||||
|
||||
mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_SUSPEND_PACKAGES);
|
||||
assertEquals(Shadows.shadowOf(textView).innerText(),
|
||||
mActivity.getString(R.string.disabled_by_policy_title_suspend_packages));
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.enterprise;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class BackupsEnabledPreferenceControllerTest {
|
||||
|
||||
private static final String KEY_BACKUPS_ENABLED = "backups_enabled";
|
||||
|
||||
private Context mContext;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
|
||||
private BackupsEnabledPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mController = new BackupsEnabledPreferenceController(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable() {
|
||||
when(mFeatureFactory.enterprisePrivacyFeatureProvider.areBackupsMandatory())
|
||||
.thenReturn(false);
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
|
||||
when(mFeatureFactory.enterprisePrivacyFeatureProvider.areBackupsMandatory())
|
||||
.thenReturn(true);
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandlePreferenceTreeClick() {
|
||||
assertThat(mController.handlePreferenceTreeClick(new Preference(mContext, null, 0, 0)))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPreferenceKey() {
|
||||
assertThat(mController.getPreferenceKey()).isEqualTo(KEY_BACKUPS_ENABLED);
|
||||
}
|
||||
}
|
||||
@@ -346,15 +346,6 @@ public class EnterprisePrivacyFeatureProviderImplTest {
|
||||
.isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAreBackupsMandatory() {
|
||||
assertThat(mProvider.areBackupsMandatory()).isFalse();
|
||||
ComponentName transportComponent = new ComponentName("test", "test");
|
||||
when(mDevicePolicyManager.getMandatoryBackupTransport())
|
||||
.thenReturn(transportComponent);
|
||||
assertThat(mProvider.areBackupsMandatory()).isTrue();
|
||||
}
|
||||
|
||||
private void resetAndInitializePackageManager() {
|
||||
reset(mPackageManager);
|
||||
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
|
||||
|
||||
@@ -99,7 +99,7 @@ public class EnterprisePrivacySettingsTest {
|
||||
|
||||
private void verifyPreferenceControllers(List<AbstractPreferenceController> controllers) {
|
||||
assertThat(controllers).isNotNull();
|
||||
assertThat(controllers.size()).isEqualTo(18);
|
||||
assertThat(controllers.size()).isEqualTo(17);
|
||||
int position = 0;
|
||||
assertThat(controllers.get(position++)).isInstanceOf(NetworkLogsPreferenceController.class);
|
||||
assertThat(controllers.get(position++)).isInstanceOf(BugReportsPreferenceController.class);
|
||||
@@ -126,8 +126,6 @@ public class EnterprisePrivacySettingsTest {
|
||||
CaCertsCurrentUserPreferenceController.class);
|
||||
assertThat(controllers.get(position++)).isInstanceOf(
|
||||
CaCertsManagedProfilePreferenceController.class);
|
||||
assertThat(controllers.get(position++)).isInstanceOf(
|
||||
BackupsEnabledPreferenceController.class);
|
||||
assertThat(controllers.get(position++)).isInstanceOf(
|
||||
PreferenceCategoryController.class);
|
||||
assertThat(controllers.get(position++)).isInstanceOf(
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.homepage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.android.settings.homepage.conditional.ConditionalContextualCard;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class ConditionalContextualCardTest {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void newInstance_changeCardType_shouldCrash() {
|
||||
new ConditionalContextualCard.Builder()
|
||||
.setCardType(ContextualCard.CardType.SUGGESTION)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCardType_shouldAlwaysBeConditional() {
|
||||
assertThat(new ConditionalContextualCard.Builder().build().getCardType())
|
||||
.isEqualTo(ContextualCard.CardType.CONDITIONAL);
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public class ConditionContextualCardControllerTest {
|
||||
|
||||
mController.onConditionsChanged();
|
||||
|
||||
verify(mController).onDataUpdated(any());
|
||||
verify(mListener).onContextualCardUpdated(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -94,7 +94,7 @@ public class ConditionContextualCardControllerTest {
|
||||
|
||||
mController.onConditionsChanged();
|
||||
|
||||
verify(mController, never()).onDataUpdated(any());
|
||||
verify(mListener, never()).onContextualCardUpdated(any());
|
||||
}
|
||||
|
||||
private class FakeConditionalCard implements ConditionalCard {
|
||||
|
||||
@@ -101,7 +101,6 @@ public class ConditionContextualCardRendererTest {
|
||||
.setMetricsConstant(1)
|
||||
.setActionText("test_action")
|
||||
.setName("test_name")
|
||||
.setCardType(ContextualCard.CardType.CONDITIONAL)
|
||||
.setTitleText("test_title")
|
||||
.setSummaryText("test_summary")
|
||||
.setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
|
||||
|
||||
@@ -189,9 +189,8 @@ public class RecentNotifyingAppsPreferenceControllerTest {
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
verify(mCategory).setTitle(R.string.recent_notifications);
|
||||
// Only add app1. app2 is skipped because of the package name, app3 skipped because
|
||||
// it's invalid app.
|
||||
verify(mCategory, times(1)).addPreference(any(Preference.class));
|
||||
// Only add app1 & app2. app3 skipped because it's invalid app.
|
||||
verify(mCategory, times(2)).addPreference(any(Preference.class));
|
||||
|
||||
verify(mSeeAllPref).setSummary(null);
|
||||
verify(mSeeAllPref).setIcon(R.drawable.ic_chevron_right_24dp);
|
||||
@@ -246,35 +245,6 @@ public class RecentNotifyingAppsPreferenceControllerTest {
|
||||
assertThat(prefs.get(0).getKey()).isEqualTo(app2.getPackage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void display_hasRecentButNoneDisplayable_showAppInfo() {
|
||||
final List<NotifyingApp> apps = new ArrayList<>();
|
||||
final NotifyingApp app1 = new NotifyingApp()
|
||||
.setPackage("com.android.phone")
|
||||
.setLastNotified(System.currentTimeMillis());
|
||||
final NotifyingApp app2 = new NotifyingApp()
|
||||
.setPackage("com.android.settings")
|
||||
.setLastNotified(System.currentTimeMillis());
|
||||
apps.add(app1);
|
||||
apps.add(app2);
|
||||
|
||||
// app1, app2 are not displayable
|
||||
when(mAppState.getEntry(app1.getPackage(), UserHandle.myUserId()))
|
||||
.thenReturn(mock(ApplicationsState.AppEntry.class));
|
||||
when(mAppState.getEntry(app2.getPackage(), UserHandle.myUserId()))
|
||||
.thenReturn(mock(ApplicationsState.AppEntry.class));
|
||||
when(mPackageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(
|
||||
new ResolveInfo());
|
||||
when(mBackend.getRecentApps()).thenReturn(apps);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
verify(mCategory, never()).addPreference(any(Preference.class));
|
||||
verify(mCategory).setTitle(null);
|
||||
verify(mSeeAllPref).setTitle(R.string.notifications_title);
|
||||
verify(mSeeAllPref).setIcon(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void display_showRecents_formatSummary() {
|
||||
final List<NotifyingApp> apps = new ArrayList<>();
|
||||
|
||||
@@ -183,6 +183,22 @@ public class WifiConfigControllerTest {
|
||||
mController.isSubmittable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSubmittable_EapToPskWithValidPassword_shouldReturnTrue() {
|
||||
final TextView password = mView.findViewById(R.id.password);
|
||||
final Spinner securitySpinner = mView.findViewById(R.id.security);
|
||||
assertThat(password).isNotNull();
|
||||
assertThat(securitySpinner).isNotNull();
|
||||
when(mAccessPoint.isSaved()).thenReturn(true);
|
||||
|
||||
// Change it from EAP to PSK
|
||||
mController.onItemSelected(securitySpinner, null, AccessPoint.SECURITY_EAP, 0);
|
||||
mController.onItemSelected(securitySpinner, null, AccessPoint.SECURITY_PSK, 0);
|
||||
password.setText(GOOD_PSK);
|
||||
|
||||
assertThat(mController.isSubmittable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSignalString_notReachable_shouldHaveNoSignalString() {
|
||||
when(mAccessPoint.isReachable()).thenReturn(false);
|
||||
|
||||
Reference in New Issue
Block a user