Merge "Expand SettingsLib ProviderTile to support non-switch type of Preferences" into udc-d1-dev
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settingslib.drawer;
|
package com.android.settingslib.drawer;
|
||||||
|
|
||||||
/** Interface for {@link SwitchController} whose instances support dynamic summary */
|
/** Interface for {@link EntryController} whose instances support dynamic summary */
|
||||||
public interface DynamicSummary {
|
public interface DynamicSummary {
|
||||||
/** @return the dynamic summary text */
|
/** @return the dynamic summary text */
|
||||||
String getDynamicSummary();
|
String getDynamicSummary();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settingslib.drawer;
|
package com.android.settingslib.drawer;
|
||||||
|
|
||||||
/** Interface for {@link SwitchController} whose instances support dynamic title */
|
/** Interface for {@link EntryController} whose instances support dynamic title */
|
||||||
public interface DynamicTitle {
|
public interface DynamicTitle {
|
||||||
/** @return the dynamic title text */
|
/** @return the dynamic title text */
|
||||||
String getDynamicTitle();
|
String getDynamicTitle();
|
||||||
|
|||||||
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settingslib.drawer;
|
||||||
|
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
|
||||||
|
|
||||||
|
import android.content.ContentProvider;
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.ProviderInfo;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract class for injecting entries to Settings.
|
||||||
|
*/
|
||||||
|
public abstract class EntriesProvider extends ContentProvider {
|
||||||
|
private static final String TAG = "EntriesProvider";
|
||||||
|
|
||||||
|
public static final String METHOD_GET_ENTRY_DATA = "getEntryData";
|
||||||
|
public static final String METHOD_GET_PROVIDER_ICON = "getProviderIcon";
|
||||||
|
public static final String METHOD_GET_DYNAMIC_TITLE = "getDynamicTitle";
|
||||||
|
public static final String METHOD_GET_DYNAMIC_SUMMARY = "getDynamicSummary";
|
||||||
|
public static final String METHOD_IS_CHECKED = "isChecked";
|
||||||
|
public static final String METHOD_ON_CHECKED_CHANGED = "onCheckedChanged";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link #METHOD_GET_ENTRY_DATA} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static final String METHOD_GET_SWITCH_DATA = "getSwitchData";
|
||||||
|
|
||||||
|
public static final String EXTRA_ENTRY_DATA = "entry_data";
|
||||||
|
public static final String EXTRA_SWITCH_CHECKED_STATE = "checked_state";
|
||||||
|
public static final String EXTRA_SWITCH_SET_CHECKED_ERROR = "set_checked_error";
|
||||||
|
public static final String EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE = "set_checked_error_message";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link #EXTRA_ENTRY_DATA} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static final String EXTRA_SWITCH_DATA = "switch_data";
|
||||||
|
|
||||||
|
private String mAuthority;
|
||||||
|
private final Map<String, EntryController> mControllerMap = new LinkedHashMap<>();
|
||||||
|
private final List<Bundle> mEntryDataList = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of {@link EntryController} for this provider.
|
||||||
|
*/
|
||||||
|
protected abstract List<? extends EntryController> createEntryControllers();
|
||||||
|
|
||||||
|
protected EntryController getController(String key) {
|
||||||
|
return mControllerMap.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attachInfo(Context context, ProviderInfo info) {
|
||||||
|
mAuthority = info.authority;
|
||||||
|
Log.i(TAG, mAuthority);
|
||||||
|
super.attachInfo(context, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreate() {
|
||||||
|
final List<? extends EntryController> controllers = createEntryControllers();
|
||||||
|
if (controllers == null || controllers.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (EntryController controller : controllers) {
|
||||||
|
final String key = controller.getKey();
|
||||||
|
if (TextUtils.isEmpty(key)) {
|
||||||
|
throw new NullPointerException("Entry key cannot be null: "
|
||||||
|
+ controller.getClass().getSimpleName());
|
||||||
|
} else if (mControllerMap.containsKey(key)) {
|
||||||
|
throw new IllegalArgumentException("Entry key " + key + " is duplicated by: "
|
||||||
|
+ controller.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.setAuthority(mAuthority);
|
||||||
|
mControllerMap.put(key, controller);
|
||||||
|
if (!(controller instanceof PrimarySwitchController)) {
|
||||||
|
mEntryDataList.add(controller.getBundle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle call(String method, String uriString, Bundle extras) {
|
||||||
|
final Bundle bundle = new Bundle();
|
||||||
|
final String key = extras != null
|
||||||
|
? extras.getString(META_DATA_PREFERENCE_KEYHINT)
|
||||||
|
: null;
|
||||||
|
if (TextUtils.isEmpty(key)) {
|
||||||
|
switch (method) {
|
||||||
|
case METHOD_GET_ENTRY_DATA:
|
||||||
|
bundle.putParcelableList(EXTRA_ENTRY_DATA, mEntryDataList);
|
||||||
|
return bundle;
|
||||||
|
case METHOD_GET_SWITCH_DATA:
|
||||||
|
bundle.putParcelableList(EXTRA_SWITCH_DATA, mEntryDataList);
|
||||||
|
return bundle;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final EntryController controller = mControllerMap.get(key);
|
||||||
|
if (controller == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case METHOD_GET_ENTRY_DATA:
|
||||||
|
case METHOD_GET_SWITCH_DATA:
|
||||||
|
if (!(controller instanceof PrimarySwitchController)) {
|
||||||
|
return controller.getBundle();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case METHOD_GET_PROVIDER_ICON:
|
||||||
|
if (controller instanceof ProviderIcon) {
|
||||||
|
return ((ProviderIcon) controller).getProviderIcon();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case METHOD_GET_DYNAMIC_TITLE:
|
||||||
|
if (controller instanceof DynamicTitle) {
|
||||||
|
bundle.putString(META_DATA_PREFERENCE_TITLE,
|
||||||
|
((DynamicTitle) controller).getDynamicTitle());
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case METHOD_GET_DYNAMIC_SUMMARY:
|
||||||
|
if (controller instanceof DynamicSummary) {
|
||||||
|
bundle.putString(META_DATA_PREFERENCE_SUMMARY,
|
||||||
|
((DynamicSummary) controller).getDynamicSummary());
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case METHOD_IS_CHECKED:
|
||||||
|
if (controller instanceof ProviderSwitch) {
|
||||||
|
bundle.putBoolean(EXTRA_SWITCH_CHECKED_STATE,
|
||||||
|
((ProviderSwitch) controller).isSwitchChecked());
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case METHOD_ON_CHECKED_CHANGED:
|
||||||
|
if (controller instanceof ProviderSwitch) {
|
||||||
|
return onSwitchCheckedChanged(extras.getBoolean(EXTRA_SWITCH_CHECKED_STATE),
|
||||||
|
(ProviderSwitch) controller);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bundle onSwitchCheckedChanged(boolean checked, ProviderSwitch controller) {
|
||||||
|
final boolean success = controller.onSwitchCheckedChanged(checked);
|
||||||
|
final Bundle bundle = new Bundle();
|
||||||
|
bundle.putBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR, !success);
|
||||||
|
if (success) {
|
||||||
|
if (controller instanceof DynamicSummary) {
|
||||||
|
((EntryController) controller).notifySummaryChanged(getContext());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bundle.putString(EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE,
|
||||||
|
controller.getSwitchErrorMessage(checked));
|
||||||
|
}
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
|
||||||
|
String sortOrder) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType(Uri uri) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Uri insert(Uri uri, ContentValues values) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,246 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settingslib.drawer;
|
||||||
|
|
||||||
|
import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_DYNAMIC_SUMMARY;
|
||||||
|
import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_DYNAMIC_TITLE;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.EXTRA_CATEGORY_KEY;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_ORDER;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_PENDING_INTENT;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SWITCH_URI;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE_URI;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A controller that manages events for switch.
|
||||||
|
*/
|
||||||
|
public abstract class EntryController {
|
||||||
|
|
||||||
|
private String mAuthority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key for this switch.
|
||||||
|
*/
|
||||||
|
public abstract String getKey();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link MetaData} for this switch.
|
||||||
|
*/
|
||||||
|
protected abstract MetaData getMetaData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify registered observers that title was updated and attempt to sync changes.
|
||||||
|
*/
|
||||||
|
public void notifyTitleChanged(Context context) {
|
||||||
|
if (this instanceof DynamicTitle) {
|
||||||
|
notifyChanged(context, METHOD_GET_DYNAMIC_TITLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify registered observers that summary was updated and attempt to sync changes.
|
||||||
|
*/
|
||||||
|
public void notifySummaryChanged(Context context) {
|
||||||
|
if (this instanceof DynamicSummary) {
|
||||||
|
notifyChanged(context, METHOD_GET_DYNAMIC_SUMMARY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAuthority(String authority) {
|
||||||
|
mAuthority = authority;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bundle getBundle() {
|
||||||
|
final MetaData metaData = getMetaData();
|
||||||
|
if (metaData == null) {
|
||||||
|
throw new NullPointerException("Should not return null in getMetaData()");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Bundle bundle = metaData.build();
|
||||||
|
final String uriString = new Uri.Builder()
|
||||||
|
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||||
|
.authority(mAuthority)
|
||||||
|
.build()
|
||||||
|
.toString();
|
||||||
|
bundle.putString(META_DATA_PREFERENCE_KEYHINT, getKey());
|
||||||
|
if (this instanceof ProviderIcon) {
|
||||||
|
bundle.putString(META_DATA_PREFERENCE_ICON_URI, uriString);
|
||||||
|
}
|
||||||
|
if (this instanceof DynamicTitle) {
|
||||||
|
bundle.putString(META_DATA_PREFERENCE_TITLE_URI, uriString);
|
||||||
|
}
|
||||||
|
if (this instanceof DynamicSummary) {
|
||||||
|
bundle.putString(META_DATA_PREFERENCE_SUMMARY_URI, uriString);
|
||||||
|
}
|
||||||
|
if (this instanceof ProviderSwitch) {
|
||||||
|
bundle.putString(META_DATA_PREFERENCE_SWITCH_URI, uriString);
|
||||||
|
}
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyChanged(Context context, String method) {
|
||||||
|
final Uri uri = TileUtils.buildUri(mAuthority, method, getKey());
|
||||||
|
context.getContentResolver().notifyChange(uri, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collects all meta data of the item.
|
||||||
|
*/
|
||||||
|
protected static class MetaData {
|
||||||
|
private String mCategory;
|
||||||
|
private int mOrder;
|
||||||
|
@DrawableRes
|
||||||
|
private int mIcon;
|
||||||
|
private int mIconBackgroundHint;
|
||||||
|
private int mIconBackgroundArgb;
|
||||||
|
private Boolean mIconTintable;
|
||||||
|
@StringRes
|
||||||
|
private int mTitleId;
|
||||||
|
private String mTitle;
|
||||||
|
@StringRes
|
||||||
|
private int mSummaryId;
|
||||||
|
private String mSummary;
|
||||||
|
private PendingIntent mPendingIntent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param category the category of the switch. This value must be from {@link CategoryKey}.
|
||||||
|
*/
|
||||||
|
public MetaData(@NonNull String category) {
|
||||||
|
mCategory = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the order of the item that should be displayed on screen. Bigger value items displays
|
||||||
|
* closer on top.
|
||||||
|
*/
|
||||||
|
public MetaData setOrder(int order) {
|
||||||
|
mOrder = order;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the icon that should be displayed for the item. */
|
||||||
|
public MetaData setIcon(@DrawableRes int icon) {
|
||||||
|
mIcon = icon;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the icon background color. The value may or may not be used by Settings app. */
|
||||||
|
public MetaData setIconBackgoundHint(int hint) {
|
||||||
|
mIconBackgroundHint = hint;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the icon background color as raw ARGB. */
|
||||||
|
public MetaData setIconBackgoundArgb(int argb) {
|
||||||
|
mIconBackgroundArgb = argb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Specify whether the icon is tintable. */
|
||||||
|
public MetaData setIconTintable(boolean tintable) {
|
||||||
|
mIconTintable = tintable;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the title that should be displayed for the item. */
|
||||||
|
public MetaData setTitle(@StringRes int id) {
|
||||||
|
mTitleId = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the title that should be displayed for the item. */
|
||||||
|
public MetaData setTitle(String title) {
|
||||||
|
mTitle = title;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the summary text that should be displayed for the item. */
|
||||||
|
public MetaData setSummary(@StringRes int id) {
|
||||||
|
mSummaryId = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the summary text that should be displayed for the item. */
|
||||||
|
public MetaData setSummary(String summary) {
|
||||||
|
mSummary = summary;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetaData setPendingIntent(PendingIntent pendingIntent) {
|
||||||
|
mPendingIntent = pendingIntent;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Bundle build() {
|
||||||
|
final Bundle bundle = new Bundle();
|
||||||
|
bundle.putString(EXTRA_CATEGORY_KEY, mCategory);
|
||||||
|
|
||||||
|
if (mOrder != 0) {
|
||||||
|
bundle.putInt(META_DATA_KEY_ORDER, mOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIcon != 0) {
|
||||||
|
bundle.putInt(META_DATA_PREFERENCE_ICON, mIcon);
|
||||||
|
}
|
||||||
|
if (mIconBackgroundHint != 0) {
|
||||||
|
bundle.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, mIconBackgroundHint);
|
||||||
|
}
|
||||||
|
if (mIconBackgroundArgb != 0) {
|
||||||
|
bundle.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, mIconBackgroundArgb);
|
||||||
|
}
|
||||||
|
if (mIconTintable != null) {
|
||||||
|
bundle.putBoolean(META_DATA_PREFERENCE_ICON_TINTABLE, mIconTintable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTitleId != 0) {
|
||||||
|
bundle.putInt(META_DATA_PREFERENCE_TITLE, mTitleId);
|
||||||
|
} else if (mTitle != null) {
|
||||||
|
bundle.putString(META_DATA_PREFERENCE_TITLE, mTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSummaryId != 0) {
|
||||||
|
bundle.putInt(META_DATA_PREFERENCE_SUMMARY, mSummaryId);
|
||||||
|
} else if (mSummary != null) {
|
||||||
|
bundle.putString(META_DATA_PREFERENCE_SUMMARY, mSummary);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPendingIntent != null) {
|
||||||
|
bundle.putParcelable(META_DATA_PREFERENCE_PENDING_INTENT, mPendingIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ package com.android.settingslib.drawer;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for {@link SwitchController} whose instances support icon provided from the content
|
* Interface for {@link EntryController} whose instances support icon provided from the content
|
||||||
* provider
|
* provider
|
||||||
*/
|
*/
|
||||||
public interface ProviderIcon {
|
public interface ProviderIcon {
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settingslib.drawer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for {@link EntryController} whose instances support switch widget provided from the
|
||||||
|
* content provider
|
||||||
|
*/
|
||||||
|
public interface ProviderSwitch {
|
||||||
|
/**
|
||||||
|
* Returns the checked state of this switch.
|
||||||
|
*/
|
||||||
|
boolean isSwitchChecked();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the checked state of this switch is changed.
|
||||||
|
*
|
||||||
|
* @return true if the checked state was successfully changed, otherwise false
|
||||||
|
*/
|
||||||
|
boolean onSwitchCheckedChanged(boolean checked);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the error message which will be toasted when {@link #onSwitchCheckedChanged} returns
|
||||||
|
* false.
|
||||||
|
*/
|
||||||
|
String getSwitchErrorMessage(boolean attemptedChecked);
|
||||||
|
}
|
||||||
@@ -75,7 +75,7 @@ public class ProviderTile extends Tile {
|
|||||||
if (infoList != null && !infoList.isEmpty()) {
|
if (infoList != null && !infoList.isEmpty()) {
|
||||||
final ProviderInfo providerInfo = infoList.get(0).providerInfo;
|
final ProviderInfo providerInfo = infoList.get(0).providerInfo;
|
||||||
mComponentInfo = providerInfo;
|
mComponentInfo = providerInfo;
|
||||||
setMetaData(TileUtils.getSwitchDataFromProvider(context, providerInfo.authority,
|
setMetaData(TileUtils.getEntryDataFromProvider(context, providerInfo.authority,
|
||||||
mKey));
|
mKey));
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Cannot find package info for "
|
Log.e(TAG, "Cannot find package info for "
|
||||||
|
|||||||
@@ -16,49 +16,22 @@
|
|||||||
|
|
||||||
package com.android.settingslib.drawer;
|
package com.android.settingslib.drawer;
|
||||||
|
|
||||||
import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_DYNAMIC_SUMMARY;
|
|
||||||
import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_DYNAMIC_TITLE;
|
|
||||||
import static com.android.settingslib.drawer.SwitchesProvider.METHOD_IS_CHECKED;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.EXTRA_CATEGORY_KEY;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_ORDER;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SWITCH_URI;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE_URI;
|
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes;
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.StringRes;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A controller that manages events for switch.
|
* A controller that manages events for switch.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link EntriesProvider} with {@link ProviderSwitch} instead.
|
||||||
*/
|
*/
|
||||||
public abstract class SwitchController {
|
@Deprecated
|
||||||
|
public abstract class SwitchController extends EntryController implements ProviderSwitch {
|
||||||
|
|
||||||
private String mAuthority;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the key for this switch.
|
* Returns the key for this switch.
|
||||||
*/
|
*/
|
||||||
public abstract String getSwitchKey();
|
public abstract String getSwitchKey();
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link MetaData} for this switch.
|
|
||||||
*/
|
|
||||||
protected abstract MetaData getMetaData();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the checked state of this switch.
|
* Returns the checked state of this switch.
|
||||||
*/
|
*/
|
||||||
@@ -76,181 +49,41 @@ public abstract class SwitchController {
|
|||||||
*/
|
*/
|
||||||
protected abstract String getErrorMessage(boolean attemptedChecked);
|
protected abstract String getErrorMessage(boolean attemptedChecked);
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Notify registered observers that title was updated and attempt to sync changes.
|
public String getKey() {
|
||||||
*/
|
return getSwitchKey();
|
||||||
public void notifyTitleChanged(Context context) {
|
|
||||||
if (this instanceof DynamicTitle) {
|
|
||||||
notifyChanged(context, METHOD_GET_DYNAMIC_TITLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSwitchChecked() {
|
||||||
|
return isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSwitchCheckedChanged(boolean checked) {
|
||||||
|
return onCheckedChanged(checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSwitchErrorMessage(boolean attemptedChecked) {
|
||||||
|
return getErrorMessage(attemptedChecked);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify registered observers that summary was updated and attempt to sync changes.
|
* Same as {@link EntryController.MetaData}, for backwards compatibility purpose.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link EntryController.MetaData} instead.
|
||||||
*/
|
*/
|
||||||
public void notifySummaryChanged(Context context) {
|
@Deprecated
|
||||||
if (this instanceof DynamicSummary) {
|
protected static class MetaData extends EntryController.MetaData {
|
||||||
notifyChanged(context, METHOD_GET_DYNAMIC_SUMMARY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify registered observers that checked state was updated and attempt to sync changes.
|
|
||||||
*/
|
|
||||||
public void notifyCheckedChanged(Context context) {
|
|
||||||
notifyChanged(context, METHOD_IS_CHECKED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAuthority(String authority) {
|
|
||||||
mAuthority = authority;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bundle getBundle() {
|
|
||||||
final MetaData metaData = getMetaData();
|
|
||||||
if (metaData == null) {
|
|
||||||
throw new NullPointerException("Should not return null in getMetaData()");
|
|
||||||
}
|
|
||||||
|
|
||||||
final Bundle bundle = metaData.build();
|
|
||||||
final String uriString = new Uri.Builder()
|
|
||||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
|
||||||
.authority(mAuthority)
|
|
||||||
.build()
|
|
||||||
.toString();
|
|
||||||
bundle.putString(META_DATA_PREFERENCE_KEYHINT, getSwitchKey());
|
|
||||||
bundle.putString(META_DATA_PREFERENCE_SWITCH_URI, uriString);
|
|
||||||
if (this instanceof ProviderIcon) {
|
|
||||||
bundle.putString(META_DATA_PREFERENCE_ICON_URI, uriString);
|
|
||||||
}
|
|
||||||
if (this instanceof DynamicTitle) {
|
|
||||||
bundle.putString(META_DATA_PREFERENCE_TITLE_URI, uriString);
|
|
||||||
}
|
|
||||||
if (this instanceof DynamicSummary) {
|
|
||||||
bundle.putString(META_DATA_PREFERENCE_SUMMARY_URI, uriString);
|
|
||||||
}
|
|
||||||
return bundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyChanged(Context context, String method) {
|
|
||||||
final Uri uri = TileUtils.buildUri(mAuthority, method, getSwitchKey());
|
|
||||||
context.getContentResolver().notifyChange(uri, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collects all meta data of the item.
|
|
||||||
*/
|
|
||||||
protected static class MetaData {
|
|
||||||
private String mCategory;
|
|
||||||
private int mOrder;
|
|
||||||
@DrawableRes
|
|
||||||
private int mIcon;
|
|
||||||
private int mIconBackgroundHint;
|
|
||||||
private int mIconBackgroundArgb;
|
|
||||||
private Boolean mIconTintable;
|
|
||||||
@StringRes
|
|
||||||
private int mTitleId;
|
|
||||||
private String mTitle;
|
|
||||||
@StringRes
|
|
||||||
private int mSummaryId;
|
|
||||||
private String mSummary;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param category the category of the switch. This value must be from {@link CategoryKey}.
|
* @param category the category of the switch. This value must be from {@link CategoryKey}.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link EntryController.MetaData} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public MetaData(@NonNull String category) {
|
public MetaData(@NonNull String category) {
|
||||||
mCategory = category;
|
super(category);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the order of the item that should be displayed on screen. Bigger value items displays
|
|
||||||
* closer on top.
|
|
||||||
*/
|
|
||||||
public MetaData setOrder(int order) {
|
|
||||||
mOrder = order;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the icon that should be displayed for the item. */
|
|
||||||
public MetaData setIcon(@DrawableRes int icon) {
|
|
||||||
mIcon = icon;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the icon background color. The value may or may not be used by Settings app. */
|
|
||||||
public MetaData setIconBackgoundHint(int hint) {
|
|
||||||
mIconBackgroundHint = hint;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the icon background color as raw ARGB. */
|
|
||||||
public MetaData setIconBackgoundArgb(int argb) {
|
|
||||||
mIconBackgroundArgb = argb;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Specify whether the icon is tintable. */
|
|
||||||
public MetaData setIconTintable(boolean tintable) {
|
|
||||||
mIconTintable = tintable;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the title that should be displayed for the item. */
|
|
||||||
public MetaData setTitle(@StringRes int id) {
|
|
||||||
mTitleId = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the title that should be displayed for the item. */
|
|
||||||
public MetaData setTitle(String title) {
|
|
||||||
mTitle = title;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the summary text that should be displayed for the item. */
|
|
||||||
public MetaData setSummary(@StringRes int id) {
|
|
||||||
mSummaryId = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the summary text that should be displayed for the item. */
|
|
||||||
public MetaData setSummary(String summary) {
|
|
||||||
mSummary = summary;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bundle build() {
|
|
||||||
final Bundle bundle = new Bundle();
|
|
||||||
bundle.putString(EXTRA_CATEGORY_KEY, mCategory);
|
|
||||||
|
|
||||||
if (mOrder != 0) {
|
|
||||||
bundle.putInt(META_DATA_KEY_ORDER, mOrder);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mIcon != 0) {
|
|
||||||
bundle.putInt(META_DATA_PREFERENCE_ICON, mIcon);
|
|
||||||
}
|
|
||||||
if (mIconBackgroundHint != 0) {
|
|
||||||
bundle.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, mIconBackgroundHint);
|
|
||||||
}
|
|
||||||
if (mIconBackgroundArgb != 0) {
|
|
||||||
bundle.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, mIconBackgroundArgb);
|
|
||||||
}
|
|
||||||
if (mIconTintable != null) {
|
|
||||||
bundle.putBoolean(META_DATA_PREFERENCE_ICON_TINTABLE, mIconTintable);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mTitleId != 0) {
|
|
||||||
bundle.putInt(META_DATA_PREFERENCE_TITLE, mTitleId);
|
|
||||||
} else if (mTitle != null) {
|
|
||||||
bundle.putString(META_DATA_PREFERENCE_TITLE, mTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mSummaryId != 0) {
|
|
||||||
bundle.putInt(META_DATA_PREFERENCE_SUMMARY, mSummaryId);
|
|
||||||
} else if (mSummary != null) {
|
|
||||||
bundle.putString(META_DATA_PREFERENCE_SUMMARY, mSummary);
|
|
||||||
}
|
|
||||||
return bundle;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,46 +16,15 @@
|
|||||||
|
|
||||||
package com.android.settingslib.drawer;
|
package com.android.settingslib.drawer;
|
||||||
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
|
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
|
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.pm.ProviderInfo;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract class for injecting switches to Settings.
|
* An abstract class for injecting switches to Settings.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link EntriesProvider} instead.
|
||||||
*/
|
*/
|
||||||
public abstract class SwitchesProvider extends ContentProvider {
|
@Deprecated
|
||||||
private static final String TAG = "SwitchesProvider";
|
public abstract class SwitchesProvider extends EntriesProvider {
|
||||||
|
|
||||||
public static final String METHOD_GET_SWITCH_DATA = "getSwitchData";
|
|
||||||
public static final String METHOD_GET_PROVIDER_ICON = "getProviderIcon";
|
|
||||||
public static final String METHOD_GET_DYNAMIC_TITLE = "getDynamicTitle";
|
|
||||||
public static final String METHOD_GET_DYNAMIC_SUMMARY = "getDynamicSummary";
|
|
||||||
public static final String METHOD_IS_CHECKED = "isChecked";
|
|
||||||
public static final String METHOD_ON_CHECKED_CHANGED = "onCheckedChanged";
|
|
||||||
|
|
||||||
public static final String EXTRA_SWITCH_DATA = "switch_data";
|
|
||||||
public static final String EXTRA_SWITCH_CHECKED_STATE = "checked_state";
|
|
||||||
public static final String EXTRA_SWITCH_SET_CHECKED_ERROR = "set_checked_error";
|
|
||||||
public static final String EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE = "set_checked_error_message";
|
|
||||||
|
|
||||||
private String mAuthority;
|
|
||||||
private final Map<String, SwitchController> mControllerMap = new LinkedHashMap<>();
|
|
||||||
private final List<Bundle> mSwitchDataList = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of {@link SwitchController} for this provider.
|
* Get a list of {@link SwitchController} for this provider.
|
||||||
@@ -63,129 +32,7 @@ public abstract class SwitchesProvider extends ContentProvider {
|
|||||||
protected abstract List<SwitchController> createSwitchControllers();
|
protected abstract List<SwitchController> createSwitchControllers();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void attachInfo(Context context, ProviderInfo info) {
|
protected List<? extends EntryController> createEntryControllers() {
|
||||||
mAuthority = info.authority;
|
return createSwitchControllers();
|
||||||
Log.i(TAG, mAuthority);
|
|
||||||
super.attachInfo(context, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreate() {
|
|
||||||
final List<SwitchController> controllers = createSwitchControllers();
|
|
||||||
if (controllers == null || controllers.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
|
|
||||||
controllers.forEach(controller -> {
|
|
||||||
final String key = controller.getSwitchKey();
|
|
||||||
if (TextUtils.isEmpty(key)) {
|
|
||||||
throw new NullPointerException("Switch key cannot be null: "
|
|
||||||
+ controller.getClass().getSimpleName());
|
|
||||||
} else if (mControllerMap.containsKey(key)) {
|
|
||||||
throw new IllegalArgumentException("Switch key " + key + " is duplicated by: "
|
|
||||||
+ controller.getClass().getSimpleName());
|
|
||||||
}
|
|
||||||
|
|
||||||
controller.setAuthority(mAuthority);
|
|
||||||
mControllerMap.put(key, controller);
|
|
||||||
if (!(controller instanceof PrimarySwitchController)) {
|
|
||||||
mSwitchDataList.add(controller.getBundle());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Bundle call(String method, String uriString, Bundle extras) {
|
|
||||||
final Bundle bundle = new Bundle();
|
|
||||||
final String key = extras != null
|
|
||||||
? extras.getString(META_DATA_PREFERENCE_KEYHINT)
|
|
||||||
: null;
|
|
||||||
if (TextUtils.isEmpty(key)) {
|
|
||||||
if (METHOD_GET_SWITCH_DATA.equals(method)) {
|
|
||||||
bundle.putParcelableList(EXTRA_SWITCH_DATA, mSwitchDataList);
|
|
||||||
return bundle;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final SwitchController controller = mControllerMap.get(key);
|
|
||||||
if (controller == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (method) {
|
|
||||||
case METHOD_GET_SWITCH_DATA:
|
|
||||||
if (!(controller instanceof PrimarySwitchController)) {
|
|
||||||
return controller.getBundle();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case METHOD_GET_PROVIDER_ICON:
|
|
||||||
if (controller instanceof ProviderIcon) {
|
|
||||||
return ((ProviderIcon) controller).getProviderIcon();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case METHOD_GET_DYNAMIC_TITLE:
|
|
||||||
if (controller instanceof DynamicTitle) {
|
|
||||||
bundle.putString(META_DATA_PREFERENCE_TITLE,
|
|
||||||
((DynamicTitle) controller).getDynamicTitle());
|
|
||||||
return bundle;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case METHOD_GET_DYNAMIC_SUMMARY:
|
|
||||||
if (controller instanceof DynamicSummary) {
|
|
||||||
bundle.putString(META_DATA_PREFERENCE_SUMMARY,
|
|
||||||
((DynamicSummary) controller).getDynamicSummary());
|
|
||||||
return bundle;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case METHOD_IS_CHECKED:
|
|
||||||
bundle.putBoolean(EXTRA_SWITCH_CHECKED_STATE, controller.isChecked());
|
|
||||||
return bundle;
|
|
||||||
case METHOD_ON_CHECKED_CHANGED:
|
|
||||||
return onCheckedChanged(extras.getBoolean(EXTRA_SWITCH_CHECKED_STATE), controller);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bundle onCheckedChanged(boolean checked, SwitchController controller) {
|
|
||||||
final boolean success = controller.onCheckedChanged(checked);
|
|
||||||
final Bundle bundle = new Bundle();
|
|
||||||
bundle.putBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR, !success);
|
|
||||||
if (success) {
|
|
||||||
if (controller instanceof DynamicSummary) {
|
|
||||||
controller.notifySummaryChanged(getContext());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bundle.putString(EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE,
|
|
||||||
controller.getErrorMessage(checked));
|
|
||||||
}
|
|
||||||
return bundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
|
|
||||||
String sortOrder) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType(Uri uri) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Uri insert(Uri uri, ContentValues values) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITL
|
|||||||
import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
|
import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
|
||||||
import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;
|
import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ComponentInfo;
|
import android.content.pm.ComponentInfo;
|
||||||
@@ -47,6 +48,7 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of a single dashboard tile that the user can select.
|
* Description of a single dashboard tile that the user can select.
|
||||||
@@ -60,6 +62,8 @@ public abstract class Tile implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public ArrayList<UserHandle> userHandle = new ArrayList<>();
|
public ArrayList<UserHandle> userHandle = new ArrayList<>();
|
||||||
|
|
||||||
|
public HashMap<UserHandle, PendingIntent> pendingIntentMap = new HashMap<>();
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
long mLastUpdateTime;
|
long mLastUpdateTime;
|
||||||
private final String mComponentPackage;
|
private final String mComponentPackage;
|
||||||
@@ -185,6 +189,13 @@ public abstract class Tile implements Parcelable {
|
|||||||
return mMetaData != null && mMetaData.containsKey(META_DATA_PREFERENCE_SWITCH_URI);
|
return mMetaData != null && mMetaData.containsKey(META_DATA_PREFERENCE_SWITCH_URI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether tile has a pending intent.
|
||||||
|
*/
|
||||||
|
public boolean hasPendingIntent() {
|
||||||
|
return !pendingIntentMap.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Title of the tile that is shown to the user.
|
* Title of the tile that is shown to the user.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -201,6 +201,13 @@ public class TileUtils {
|
|||||||
public static final String META_DATA_PREFERENCE_SWITCH_URI =
|
public static final String META_DATA_PREFERENCE_SWITCH_URI =
|
||||||
"com.android.settings.switch_uri";
|
"com.android.settings.switch_uri";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the meta-data item that can be set from the content provider providing the intent
|
||||||
|
* that will be executed when the user taps on the preference.
|
||||||
|
*/
|
||||||
|
public static final String META_DATA_PREFERENCE_PENDING_INTENT =
|
||||||
|
"com.android.settings.pending_intent";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value for {@link #META_DATA_KEY_PROFILE}. When the device has a managed profile,
|
* Value for {@link #META_DATA_KEY_PROFILE}. When the device has a managed profile,
|
||||||
* the app will always be run in the primary profile.
|
* the app will always be run in the primary profile.
|
||||||
@@ -331,12 +338,12 @@ public class TileUtils {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final ProviderInfo providerInfo = resolved.providerInfo;
|
final ProviderInfo providerInfo = resolved.providerInfo;
|
||||||
final List<Bundle> switchData = getSwitchDataFromProvider(context,
|
final List<Bundle> entryData = getEntryDataFromProvider(context,
|
||||||
providerInfo.authority);
|
providerInfo.authority);
|
||||||
if (switchData == null || switchData.isEmpty()) {
|
if (entryData == null || entryData.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (Bundle metaData : switchData) {
|
for (Bundle metaData : entryData) {
|
||||||
loadTile(user, addedCache, defaultCategory, outTiles, intent, metaData,
|
loadTile(user, addedCache, defaultCategory, outTiles, intent, metaData,
|
||||||
providerInfo);
|
providerInfo);
|
||||||
}
|
}
|
||||||
@@ -386,28 +393,44 @@ public class TileUtils {
|
|||||||
if (!tile.userHandle.contains(user)) {
|
if (!tile.userHandle.contains(user)) {
|
||||||
tile.userHandle.add(user);
|
tile.userHandle.add(user);
|
||||||
}
|
}
|
||||||
|
if (metaData.containsKey(META_DATA_PREFERENCE_PENDING_INTENT)) {
|
||||||
|
tile.pendingIntentMap.put(
|
||||||
|
user, metaData.getParcelable(META_DATA_PREFERENCE_PENDING_INTENT));
|
||||||
|
}
|
||||||
if (!outTiles.contains(tile)) {
|
if (!outTiles.contains(tile)) {
|
||||||
outTiles.add(tile);
|
outTiles.add(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the switch data of the key specified from the provider */
|
/** Returns the entry data of the key specified from the provider */
|
||||||
// TODO(b/144732809): rearrange methods by access level modifiers
|
// TODO(b/144732809): rearrange methods by access level modifiers
|
||||||
static Bundle getSwitchDataFromProvider(Context context, String authority, String key) {
|
static Bundle getEntryDataFromProvider(Context context, String authority, String key) {
|
||||||
final Map<String, IContentProvider> providerMap = new ArrayMap<>();
|
final Map<String, IContentProvider> providerMap = new ArrayMap<>();
|
||||||
final Uri uri = buildUri(authority, SwitchesProvider.METHOD_GET_SWITCH_DATA, key);
|
final Uri uri = buildUri(authority, EntriesProvider.METHOD_GET_ENTRY_DATA, key);
|
||||||
return getBundleFromUri(context, uri, providerMap, null /* bundle */);
|
Bundle result = getBundleFromUri(context, uri, providerMap, null /* bundle */);
|
||||||
|
if (result == null) {
|
||||||
|
Uri fallbackUri = buildUri(authority, EntriesProvider.METHOD_GET_SWITCH_DATA, key);
|
||||||
|
result = getBundleFromUri(context, fallbackUri, providerMap, null /* bundle */);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns all switch data from the provider */
|
/** Returns all entry data from the provider */
|
||||||
private static List<Bundle> getSwitchDataFromProvider(Context context, String authority) {
|
private static List<Bundle> getEntryDataFromProvider(Context context, String authority) {
|
||||||
final Map<String, IContentProvider> providerMap = new ArrayMap<>();
|
final Map<String, IContentProvider> providerMap = new ArrayMap<>();
|
||||||
final Uri uri = buildUri(authority, SwitchesProvider.METHOD_GET_SWITCH_DATA);
|
final Uri uri = buildUri(authority, EntriesProvider.METHOD_GET_ENTRY_DATA);
|
||||||
final Bundle result = getBundleFromUri(context, uri, providerMap, null /* bundle */);
|
final Bundle result = getBundleFromUri(context, uri, providerMap, null /* bundle */);
|
||||||
return result != null
|
if (result != null) {
|
||||||
? result.getParcelableArrayList(SwitchesProvider.EXTRA_SWITCH_DATA)
|
return result.getParcelableArrayList(EntriesProvider.EXTRA_ENTRY_DATA);
|
||||||
|
} else {
|
||||||
|
Uri fallbackUri = buildUri(authority, EntriesProvider.METHOD_GET_SWITCH_DATA);
|
||||||
|
Bundle fallbackResult =
|
||||||
|
getBundleFromUri(context, fallbackUri, providerMap, null /* bundle */);
|
||||||
|
return fallbackResult != null
|
||||||
|
? fallbackResult.getParcelableArrayList(EntriesProvider.EXTRA_SWITCH_DATA)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the complete uri from the meta data key of the tile.
|
* Returns the complete uri from the meta data key of the tile.
|
||||||
|
|||||||
@@ -209,8 +209,7 @@ public class MetricsFeatureProvider {
|
|||||||
}
|
}
|
||||||
final ComponentName cn = intent.getComponent();
|
final ComponentName cn = intent.getComponent();
|
||||||
final String key = cn != null ? cn.flattenToString() : intent.getAction();
|
final String key = cn != null ? cn.flattenToString() : intent.getAction();
|
||||||
return logSettingsTileClick(key + (isWorkProfile ? "/work" : "/personal"),
|
return logSettingsTileClickWithProfile(key, sourceMetricsCategory, isWorkProfile);
|
||||||
sourceMetricsCategory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,4 +225,20 @@ public class MetricsFeatureProvider {
|
|||||||
clicked(sourceMetricsCategory, logKey);
|
clicked(sourceMetricsCategory, logKey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs an event when the setting key is clicked with a specific profile from Profile select
|
||||||
|
* dialog.
|
||||||
|
*
|
||||||
|
* @return true if the key is loggable, otherwise false
|
||||||
|
*/
|
||||||
|
public boolean logSettingsTileClickWithProfile(String logKey, int sourceMetricsCategory,
|
||||||
|
boolean isWorkProfile) {
|
||||||
|
if (TextUtils.isEmpty(logKey)) {
|
||||||
|
// Not loggable
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
clicked(sourceMetricsCategory, logKey + (isWorkProfile ? "/work" : "/personal"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,4 +203,24 @@ public class MetricsFeatureProviderTest {
|
|||||||
assertThat(loggable).isFalse();
|
assertThat(loggable).isFalse();
|
||||||
verifyNoMoreInteractions(mLogWriter);
|
verifyNoMoreInteractions(mLogWriter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void logSettingsTileClickWithProfile_isPersonalProfile_shouldTagPersonal() {
|
||||||
|
final String key = "abc";
|
||||||
|
final boolean loggable = mProvider.logSettingsTileClickWithProfile(key,
|
||||||
|
MetricsEvent.SETTINGS_GESTURES, false);
|
||||||
|
|
||||||
|
assertThat(loggable).isTrue();
|
||||||
|
verify(mLogWriter).clicked(MetricsEvent.SETTINGS_GESTURES, "abc/personal");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void logSettingsTileClickWithProfile_isWorkProfile_shouldTagWork() {
|
||||||
|
final String key = "abc";
|
||||||
|
final boolean loggable = mProvider.logSettingsTileClickWithProfile(key,
|
||||||
|
MetricsEvent.SETTINGS_GESTURES, true);
|
||||||
|
|
||||||
|
assertThat(loggable).isTrue();
|
||||||
|
verify(mLogWriter).clicked(MetricsEvent.SETTINGS_GESTURES, "abc/work");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,12 +24,14 @@ import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -191,4 +193,20 @@ public class ActivityTileTest {
|
|||||||
|
|
||||||
assertThat(tile.getTitle(RuntimeEnvironment.application)).isNull();
|
assertThat(tile.getTitle(RuntimeEnvironment.application)).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hasPendingIntent_empty_returnsFalse() {
|
||||||
|
final Tile tile = new ActivityTile(mActivityInfo, "category");
|
||||||
|
|
||||||
|
assertThat(tile.hasPendingIntent()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hasPendingIntent_notEmpty_returnsTrue() {
|
||||||
|
final Tile tile = new ActivityTile(mActivityInfo, "category");
|
||||||
|
tile.pendingIntentMap.put(
|
||||||
|
UserHandle.CURRENT, PendingIntent.getActivity(mContext, 0, new Intent(), 0));
|
||||||
|
|
||||||
|
assertThat(tile.hasPendingIntent()).isTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,472 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settingslib.drawer;
|
||||||
|
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.EXTRA_ENTRY_DATA;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.EXTRA_SWITCH_CHECKED_STATE;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.EXTRA_SWITCH_DATA;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.EXTRA_SWITCH_SET_CHECKED_ERROR;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.METHOD_GET_DYNAMIC_SUMMARY;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.METHOD_GET_DYNAMIC_TITLE;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.METHOD_GET_ENTRY_DATA;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.METHOD_GET_PROVIDER_ICON;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.METHOD_GET_SWITCH_DATA;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.METHOD_IS_CHECKED;
|
||||||
|
import static com.android.settingslib.drawer.EntriesProvider.METHOD_ON_CHECKED_CHANGED;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_PENDING_INTENT;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ProviderInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.android.settingslib.drawer.EntryController.MetaData;
|
||||||
|
import com.android.settingslib.drawer.PrimarySwitchControllerTest.TestPrimarySwitchController;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public class EntriesProviderTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private ProviderInfo mProviderInfo;
|
||||||
|
|
||||||
|
private TestEntriesProvider mEntriesProvider;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mContext = RuntimeEnvironment.application;
|
||||||
|
mEntriesProvider = new TestEntriesProvider();
|
||||||
|
mProviderInfo = new ProviderInfo();
|
||||||
|
mProviderInfo.authority = "auth";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void attachInfo_noController_shouldThrowIllegalArgumentException() {
|
||||||
|
thrown.expect(IllegalArgumentException.class);
|
||||||
|
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void attachInfo_NoKeyInController_shouldThrowNullPointerException() {
|
||||||
|
thrown.expect(NullPointerException.class);
|
||||||
|
final TestEntryController controller = new TestEntryController();
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void attachInfo_NoMetaDataInController_shouldThrowNullPointerException() {
|
||||||
|
thrown.expect(NullPointerException.class);
|
||||||
|
final TestEntryController controller = new TestEntryController();
|
||||||
|
controller.setKey("123");
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void attachInfo_duplicateKey_shouldThrowIllegalArgumentException() {
|
||||||
|
thrown.expect(IllegalArgumentException.class);
|
||||||
|
final TestEntryController controller1 = new TestEntryController();
|
||||||
|
final TestEntryController controller2 = new TestEntryController();
|
||||||
|
controller1.setKey("123");
|
||||||
|
controller2.setKey("123");
|
||||||
|
controller1.setMetaData(new MetaData("category"));
|
||||||
|
controller2.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller1);
|
||||||
|
mEntriesProvider.addController(controller2);
|
||||||
|
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void attachInfo_hasDifferentControllers_shouldNotThrowException() {
|
||||||
|
final TestEntryController controller1 = new TestEntryController();
|
||||||
|
final TestEntryController controller2 = new TestEntryController();
|
||||||
|
controller1.setKey("123");
|
||||||
|
controller2.setKey("456");
|
||||||
|
controller1.setMetaData(new MetaData("category"));
|
||||||
|
controller2.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller1);
|
||||||
|
mEntriesProvider.addController(controller2);
|
||||||
|
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getEntryData_shouldNotReturnPrimarySwitchData() {
|
||||||
|
final EntryController controller = new TestPrimarySwitchController("123");
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle switchData = mEntriesProvider.call(METHOD_GET_ENTRY_DATA, "uri",
|
||||||
|
null /* extras*/);
|
||||||
|
|
||||||
|
final ArrayList<Bundle> dataList = switchData.getParcelableArrayList(EXTRA_ENTRY_DATA);
|
||||||
|
assertThat(dataList).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getEntryData_shouldReturnDataList() {
|
||||||
|
final TestEntryController controller = new TestEntryController();
|
||||||
|
final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category").setPendingIntent(pendingIntent));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle entryData = mEntriesProvider.call(METHOD_GET_ENTRY_DATA, "uri",
|
||||||
|
null /* extras*/);
|
||||||
|
|
||||||
|
final ArrayList<Bundle> dataList = entryData.getParcelableArrayList(EXTRA_ENTRY_DATA);
|
||||||
|
assertThat(dataList).hasSize(1);
|
||||||
|
assertThat(dataList.get(0).getString(META_DATA_PREFERENCE_KEYHINT)).isEqualTo("123");
|
||||||
|
assertThat(dataList.get(0).getParcelable(META_DATA_PREFERENCE_PENDING_INTENT,
|
||||||
|
PendingIntent.class))
|
||||||
|
.isEqualTo(pendingIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSwitchData_shouldReturnDataList() {
|
||||||
|
final TestEntryController controller = new TestEntryController();
|
||||||
|
final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category").setPendingIntent(pendingIntent));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle entryData = mEntriesProvider.call(METHOD_GET_SWITCH_DATA, "uri",
|
||||||
|
null /* extras*/);
|
||||||
|
|
||||||
|
final ArrayList<Bundle> dataList = entryData.getParcelableArrayList(EXTRA_SWITCH_DATA);
|
||||||
|
assertThat(dataList).hasSize(1);
|
||||||
|
assertThat(dataList.get(0).getString(META_DATA_PREFERENCE_KEYHINT)).isEqualTo("123");
|
||||||
|
assertThat(dataList.get(0).getParcelable(META_DATA_PREFERENCE_PENDING_INTENT,
|
||||||
|
PendingIntent.class))
|
||||||
|
.isEqualTo(pendingIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getEntryDataByKey_shouldReturnData() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestEntryController controller = new TestEntryController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle entryData = mEntriesProvider.call(METHOD_GET_ENTRY_DATA, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(entryData.getString(META_DATA_PREFERENCE_KEYHINT)).isEqualTo("123");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSwitchDataByKey_shouldReturnData() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestEntryController controller = new TestEntryController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle entryData = mEntriesProvider.call(METHOD_GET_SWITCH_DATA, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(entryData.getString(META_DATA_PREFERENCE_KEYHINT)).isEqualTo("123");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isSwitchChecked_shouldReturnCheckedState() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestSwitchController controller = new TestSwitchController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
controller.setSwitchChecked(true);
|
||||||
|
Bundle result = mEntriesProvider.call(METHOD_IS_CHECKED, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(result.getBoolean(EXTRA_SWITCH_CHECKED_STATE)).isTrue();
|
||||||
|
|
||||||
|
controller.setSwitchChecked(false);
|
||||||
|
result = mEntriesProvider.call(METHOD_IS_CHECKED, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(result.getBoolean(EXTRA_SWITCH_CHECKED_STATE)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getProviderIcon_noImplementInterface_shouldReturnNull() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestEntryController controller = new TestEntryController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle iconBundle = mEntriesProvider.call(METHOD_GET_PROVIDER_ICON, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(iconBundle).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getProviderIcon_implementInterface_shouldReturnIcon() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestEntryController controller = new TestDynamicController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle iconBundle = mEntriesProvider.call(METHOD_GET_PROVIDER_ICON, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(iconBundle).isEqualTo(TestDynamicController.ICON_BUNDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getDynamicTitle_noImplementInterface_shouldReturnNull() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestEntryController controller = new TestEntryController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle result = mEntriesProvider.call(METHOD_GET_DYNAMIC_TITLE, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(result).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getDynamicTitle_implementInterface_shouldReturnTitle() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestEntryController controller = new TestDynamicController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle result = mEntriesProvider.call(METHOD_GET_DYNAMIC_TITLE, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(result.getString(META_DATA_PREFERENCE_TITLE))
|
||||||
|
.isEqualTo(TestDynamicController.TITLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getDynamicSummary_noImplementInterface_shouldReturnNull() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestEntryController controller = new TestEntryController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle result = mEntriesProvider.call(METHOD_GET_DYNAMIC_SUMMARY, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(result).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getDynamicSummary_implementInterface_shouldReturnSummary() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestEntryController controller = new TestDynamicController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle result = mEntriesProvider.call(METHOD_GET_DYNAMIC_SUMMARY, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(result.getString(META_DATA_PREFERENCE_SUMMARY))
|
||||||
|
.isEqualTo(TestDynamicController.SUMMARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onSwitchCheckedChangedSuccess_shouldReturnNoError() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestSwitchController controller = new TestSwitchController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle result = mEntriesProvider.call(METHOD_ON_CHECKED_CHANGED, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(result.getBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onSwitchCheckedChangedFailed_shouldReturnErrorMessage() {
|
||||||
|
final Bundle extras = new Bundle();
|
||||||
|
extras.putString(META_DATA_PREFERENCE_KEYHINT, "123");
|
||||||
|
final TestSwitchController controller = new TestSwitchController();
|
||||||
|
controller.setKey("123");
|
||||||
|
controller.setMetaData(new MetaData("category"));
|
||||||
|
controller.setSwitchErrorMessage("error");
|
||||||
|
mEntriesProvider.addController(controller);
|
||||||
|
mEntriesProvider.attachInfo(mContext, mProviderInfo);
|
||||||
|
|
||||||
|
final Bundle result = mEntriesProvider.call(METHOD_ON_CHECKED_CHANGED, "uri", extras);
|
||||||
|
|
||||||
|
assertThat(result.getBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR)).isTrue();
|
||||||
|
assertThat(result.getString(EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE)).isEqualTo("error");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestEntriesProvider extends EntriesProvider {
|
||||||
|
|
||||||
|
private List<EntryController> mControllers;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<EntryController> createEntryControllers() {
|
||||||
|
return mControllers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addController(EntryController controller) {
|
||||||
|
if (mControllers == null) {
|
||||||
|
mControllers = new ArrayList<>();
|
||||||
|
}
|
||||||
|
mControllers.add(controller);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestEntryController extends EntryController {
|
||||||
|
|
||||||
|
private String mKey;
|
||||||
|
private MetaData mMetaData;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return mKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MetaData getMetaData() {
|
||||||
|
return mMetaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setKey(String key) {
|
||||||
|
mKey = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMetaData(MetaData metaData) {
|
||||||
|
mMetaData = metaData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestSwitchController extends EntryController implements ProviderSwitch {
|
||||||
|
|
||||||
|
private String mKey;
|
||||||
|
private MetaData mMetaData;
|
||||||
|
private boolean mChecked;
|
||||||
|
private String mErrorMsg;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return mKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MetaData getMetaData() {
|
||||||
|
return mMetaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSwitchChecked() {
|
||||||
|
return mChecked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSwitchCheckedChanged(boolean checked) {
|
||||||
|
return mErrorMsg == null ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSwitchErrorMessage(boolean attemptedChecked) {
|
||||||
|
return mErrorMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setKey(String key) {
|
||||||
|
mKey = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMetaData(MetaData metaData) {
|
||||||
|
mMetaData = metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSwitchChecked(boolean checked) {
|
||||||
|
mChecked = checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSwitchErrorMessage(String errorMsg) {
|
||||||
|
mErrorMsg = errorMsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestDynamicController extends TestEntryController
|
||||||
|
implements ProviderIcon, DynamicTitle, DynamicSummary {
|
||||||
|
|
||||||
|
static final String TITLE = "title";
|
||||||
|
static final String SUMMARY = "summary";
|
||||||
|
static final Bundle ICON_BUNDLE = new Bundle();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle getProviderIcon() {
|
||||||
|
return ICON_BUNDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDynamicTitle() {
|
||||||
|
return TITLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDynamicSummary() {
|
||||||
|
return SUMMARY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,12 +25,14 @@ import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.ProviderInfo;
|
import android.content.pm.ProviderInfo;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
@@ -173,13 +175,29 @@ public class ProviderTileTest {
|
|||||||
assertThat(tile.mLastUpdateTime).isNotEqualTo(staleTimeStamp);
|
assertThat(tile.mLastUpdateTime).isNotEqualTo(staleTimeStamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hasPendingIntent_empty_returnsFalse() {
|
||||||
|
final Tile tile = new ProviderTile(mProviderInfo, "category", mMetaData);
|
||||||
|
|
||||||
|
assertThat(tile.hasPendingIntent()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hasPendingIntent_notEmpty_returnsTrue() {
|
||||||
|
final Tile tile = new ProviderTile(mProviderInfo, "category", mMetaData);
|
||||||
|
tile.pendingIntentMap.put(
|
||||||
|
UserHandle.CURRENT, PendingIntent.getActivity(mContext, 0, new Intent(), 0));
|
||||||
|
|
||||||
|
assertThat(tile.hasPendingIntent()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
@Implements(TileUtils.class)
|
@Implements(TileUtils.class)
|
||||||
private static class ShadowTileUtils {
|
private static class ShadowTileUtils {
|
||||||
|
|
||||||
private static Bundle sMetaData;
|
private static Bundle sMetaData;
|
||||||
|
|
||||||
@Implementation
|
@Implementation
|
||||||
protected static Bundle getSwitchDataFromProvider(Context context, String authority,
|
protected static Bundle getEntryDataFromProvider(Context context, String authority,
|
||||||
String key) {
|
String key) {
|
||||||
return sMetaData;
|
return sMetaData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_PROFILE;
|
|||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI;
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI;
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
|
||||||
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_PENDING_INTENT;
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
|
||||||
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI;
|
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI;
|
||||||
import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
|
import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
|
||||||
@@ -40,6 +41,7 @@ import static org.mockito.Mockito.when;
|
|||||||
import static org.robolectric.RuntimeEnvironment.application;
|
import static org.robolectric.RuntimeEnvironment.application;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -350,6 +352,53 @@ public class TileUtilsTest {
|
|||||||
assertThat(outTiles).isEmpty();
|
assertThat(outTiles).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadTilesForAction_multipleUserProfiles_updatesUserHandle() {
|
||||||
|
Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
|
||||||
|
List<Tile> outTiles = new ArrayList<>();
|
||||||
|
List<ResolveInfo> info = new ArrayList<>();
|
||||||
|
ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
|
||||||
|
URI_GET_SUMMARY, null, 123, PROFILE_ALL);
|
||||||
|
info.add(resolveInfo);
|
||||||
|
|
||||||
|
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
|
||||||
|
.thenReturn(info);
|
||||||
|
|
||||||
|
TileUtils.loadTilesForAction(mContext, UserHandle.CURRENT, IA_SETTINGS_ACTION,
|
||||||
|
addedCache, null /* defaultCategory */, outTiles, false /* requiresSettings */);
|
||||||
|
TileUtils.loadTilesForAction(mContext, new UserHandle(10), IA_SETTINGS_ACTION,
|
||||||
|
addedCache, null /* defaultCategory */, outTiles, false /* requiresSettings */);
|
||||||
|
|
||||||
|
assertThat(outTiles).hasSize(1);
|
||||||
|
assertThat(outTiles.get(0).userHandle)
|
||||||
|
.containsExactly(UserHandle.CURRENT, new UserHandle(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadTilesForAction_withPendingIntent_updatesPendingIntentMap() {
|
||||||
|
Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
|
||||||
|
List<Tile> outTiles = new ArrayList<>();
|
||||||
|
List<ResolveInfo> info = new ArrayList<>();
|
||||||
|
ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
|
||||||
|
URI_GET_SUMMARY, null, 123, PROFILE_ALL);
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
|
||||||
|
resolveInfo.activityInfo.metaData
|
||||||
|
.putParcelable(META_DATA_PREFERENCE_PENDING_INTENT, pendingIntent);
|
||||||
|
info.add(resolveInfo);
|
||||||
|
|
||||||
|
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
|
||||||
|
.thenReturn(info);
|
||||||
|
|
||||||
|
TileUtils.loadTilesForAction(mContext, UserHandle.CURRENT, IA_SETTINGS_ACTION,
|
||||||
|
addedCache, null /* defaultCategory */, outTiles, false /* requiresSettings */);
|
||||||
|
TileUtils.loadTilesForAction(mContext, new UserHandle(10), IA_SETTINGS_ACTION,
|
||||||
|
addedCache, null /* defaultCategory */, outTiles, false /* requiresSettings */);
|
||||||
|
|
||||||
|
assertThat(outTiles).hasSize(1);
|
||||||
|
assertThat(outTiles.get(0).pendingIntentMap).containsExactly(
|
||||||
|
UserHandle.CURRENT, pendingIntent, new UserHandle(10), pendingIntent);
|
||||||
|
}
|
||||||
|
|
||||||
public static ResolveInfo newInfo(boolean systemApp, String category) {
|
public static ResolveInfo newInfo(boolean systemApp, String category) {
|
||||||
return newInfo(systemApp, category, null);
|
return newInfo(systemApp, category, null);
|
||||||
}
|
}
|
||||||
@@ -424,7 +473,7 @@ public class TileUtilsTest {
|
|||||||
private static Bundle sMetaData;
|
private static Bundle sMetaData;
|
||||||
|
|
||||||
@Implementation
|
@Implementation
|
||||||
protected static List<Bundle> getSwitchDataFromProvider(Context context, String authority) {
|
protected static List<Bundle> getEntryDataFromProvider(Context context, String authority) {
|
||||||
return Arrays.asList(sMetaData);
|
return Arrays.asList(sMetaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user