Merge "Lazily loading the widget providers to avoid loading app-resources on userUnlock"
This commit is contained in:
committed by
Android (Google) Code Review
commit
f4e7856ce9
@@ -89,10 +89,12 @@ import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.IntArray;
|
||||
import android.util.LongSparseArray;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.util.SparseLongArray;
|
||||
import android.util.TypedValue;
|
||||
@@ -105,6 +107,7 @@ import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.app.SuspendedAppActivity;
|
||||
import com.android.internal.app.UnlaunchableAppActivity;
|
||||
import com.android.internal.appwidget.IAppWidgetHost;
|
||||
@@ -161,8 +164,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
|
||||
private static final int UNKNOWN_UID = -1;
|
||||
|
||||
private static final int LOADED_PROFILE_ID = -1;
|
||||
|
||||
private static final int UNKNOWN_USER_ID = -10;
|
||||
|
||||
// Bump if the stored widgets need to be upgraded.
|
||||
@@ -220,7 +221,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
private final ArraySet<Pair<Integer, String>> mPackagesWithBindWidgetPermission =
|
||||
new ArraySet<>();
|
||||
|
||||
private final SparseIntArray mLoadedUserIds = new SparseIntArray();
|
||||
private final SparseBooleanArray mLoadedUserIds = new SparseBooleanArray();
|
||||
|
||||
private final Object mWidgetPackagesLock = new Object();
|
||||
private final SparseArray<ArraySet<String>> mWidgetPackages = new SparseArray<>();
|
||||
@@ -525,7 +526,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
boolean suspended;
|
||||
try {
|
||||
suspended = mPackageManager.isPackageSuspendedForUser(
|
||||
provider.info.provider.getPackageName(), provider.getUserId());
|
||||
provider.id.componentName.getPackageName(), provider.getUserId());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Package not found.
|
||||
suspended = false;
|
||||
@@ -563,7 +564,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
Provider provider = mProviders.get(i);
|
||||
int providerUserId = provider.getUserId();
|
||||
if (providerUserId != profileId
|
||||
|| !packages.contains(provider.info.provider.getPackageName())) {
|
||||
|| !packages.contains(provider.id.componentName.getPackageName())) {
|
||||
continue;
|
||||
}
|
||||
if (provider.setMaskedBySuspendedPackageLocked(suspended)) {
|
||||
@@ -624,7 +625,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
if (widgetCount == 0) {
|
||||
return;
|
||||
}
|
||||
final String providerPackage = provider.info.provider.getPackageName();
|
||||
final String providerPackage = provider.id.componentName.getPackageName();
|
||||
final int providerUserId = provider.getUserId();
|
||||
Bitmap iconBitmap = createMaskedWidgetBitmap(providerPackage, providerUserId);
|
||||
if (iconBitmap == null) {
|
||||
@@ -725,35 +726,17 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
}
|
||||
final int[] profileIds = mSecurityPolicy.getEnabledGroupProfileIds(userId);
|
||||
|
||||
// Careful lad, we may have already loaded the state for some
|
||||
// group members, so check before loading and read only the
|
||||
// state for the new member(s).
|
||||
int newMemberCount = 0;
|
||||
final int profileIdCount = profileIds.length;
|
||||
for (int i = 0; i < profileIdCount; i++) {
|
||||
final int profileId = profileIds[i];
|
||||
if (mLoadedUserIds.indexOfKey(profileId) >= 0) {
|
||||
profileIds[i] = LOADED_PROFILE_ID;
|
||||
} else {
|
||||
newMemberCount++;
|
||||
IntArray newIds = new IntArray(1);
|
||||
for (int profileId : profileIds) {
|
||||
if (!mLoadedUserIds.get(profileId)) {
|
||||
mLoadedUserIds.put(profileId, true);
|
||||
newIds.add(profileId);
|
||||
}
|
||||
}
|
||||
|
||||
if (newMemberCount <= 0) {
|
||||
if (newIds.size() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int newMemberIndex = 0;
|
||||
final int[] newProfileIds = new int[newMemberCount];
|
||||
for (int i = 0; i < profileIdCount; i++) {
|
||||
final int profileId = profileIds[i];
|
||||
if (profileId != LOADED_PROFILE_ID) {
|
||||
mLoadedUserIds.put(profileId, profileId);
|
||||
newProfileIds[newMemberIndex] = profileId;
|
||||
newMemberIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
final int[] newProfileIds = newIds.toArray();
|
||||
clearProvidersAndHostsTagsLocked();
|
||||
|
||||
loadGroupWidgetProvidersLocked(newProfileIds);
|
||||
@@ -772,7 +755,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
if (args.length > 0 && "--proto".equals(args[0])) {
|
||||
dumpProto(fd);
|
||||
} else {
|
||||
dumpInternal(pw);
|
||||
dumpInternalLocked(pw);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -816,11 +799,11 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
private void dumpInternal(PrintWriter pw) {
|
||||
private void dumpInternalLocked(PrintWriter pw) {
|
||||
int N = mProviders.size();
|
||||
pw.println("Providers:");
|
||||
for (int i = 0; i < N; i++) {
|
||||
dumpProvider(mProviders.get(i), i, pw);
|
||||
dumpProviderLocked(mProviders.get(i), i, pw);
|
||||
}
|
||||
|
||||
N = mWidgets.size();
|
||||
@@ -850,7 +833,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
public ParceledListSlice<PendingHostUpdate> startListening(IAppWidgetHost callbacks,
|
||||
String callingPackage, int hostId, int[] appWidgetIds) {
|
||||
final int userId = UserHandle.getCallingUserId();
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.i(TAG, "startListening() " + userId);
|
||||
}
|
||||
@@ -879,7 +861,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
LongSparseArray<PendingHostUpdate> updatesMap = new LongSparseArray<>();
|
||||
for (int i = 0; i < N; i++) {
|
||||
updatesMap.clear();
|
||||
host.getPendingUpdatesForId(appWidgetIds[i], updatesMap);
|
||||
host.getPendingUpdatesForIdLocked(mContext, appWidgetIds[i], updatesMap);
|
||||
// We key the updates based on request id, so that the values are sorted in the
|
||||
// order they were received.
|
||||
int m = updatesMap.size();
|
||||
@@ -1090,7 +1072,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
intent.setComponent(provider.info.configure);
|
||||
intent.setComponent(provider.getInfoLocked(mContext).configure);
|
||||
intent.setFlags(secureFlags);
|
||||
|
||||
// All right, create the sender.
|
||||
@@ -1434,7 +1416,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
Binder.getCallingUid(), callingPackage);
|
||||
|
||||
if (widget != null && widget.provider != null && !widget.provider.zombie) {
|
||||
return cloneIfLocalBinder(widget.provider.info);
|
||||
return cloneIfLocalBinder(widget.provider.getInfoLocked(mContext));
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -1644,14 +1626,14 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
|
||||
String keyToUse = metadataKey == null
|
||||
? AppWidgetManager.META_DATA_APPWIDGET_PROVIDER : metadataKey;
|
||||
AppWidgetProviderInfo info =
|
||||
parseAppWidgetProviderInfo(providerId, provider.info.providerInfo, keyToUse);
|
||||
AppWidgetProviderInfo info = parseAppWidgetProviderInfo(mContext, providerId,
|
||||
provider.getPartialInfoLocked().providerInfo, keyToUse);
|
||||
if (info == null) {
|
||||
throw new IllegalArgumentException("Unable to parse " + keyToUse
|
||||
+ " meta-data to a valid AppWidget provider");
|
||||
}
|
||||
|
||||
provider.info = info;
|
||||
provider.setInfoLocked(info);
|
||||
provider.infoTag = metadataKey;
|
||||
|
||||
// Update all widgets for this provider
|
||||
@@ -1701,7 +1683,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
if (provider == null || provider.zombie) {
|
||||
return false;
|
||||
}
|
||||
info = provider.info;
|
||||
info = provider.getInfoLocked(mContext);
|
||||
if ((info.widgetCategory & AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN) == 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -1739,7 +1721,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
final int providerCount = mProviders.size();
|
||||
for (int i = 0; i < providerCount; i++) {
|
||||
Provider provider = mProviders.get(i);
|
||||
AppWidgetProviderInfo info = provider.info;
|
||||
AppWidgetProviderInfo info = provider.getInfoLocked(mContext);
|
||||
|
||||
// Ignore an invalid provider, one not matching the filter,
|
||||
// or one that isn't in the given package, if any.
|
||||
@@ -1907,7 +1889,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
try {
|
||||
mContext.bindServiceAsUser(intent, conn,
|
||||
Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
|
||||
widget.provider.info.getProfile());
|
||||
widget.provider.id.getProfile());
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
@@ -2102,7 +2084,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = widget.host;
|
||||
args.arg2 = widget.host.callbacks;
|
||||
args.arg3 = widget.provider.info;
|
||||
args.arg3 = widget.provider.getInfoLocked(mContext);
|
||||
args.arg4 = requestId;
|
||||
args.argi1 = widget.appWidgetId;
|
||||
|
||||
@@ -2312,31 +2294,34 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
ri.activityInfo.name);
|
||||
ProviderId providerId = new ProviderId(ri.activityInfo.applicationInfo.uid, componentName);
|
||||
|
||||
Provider provider = parseProviderInfoXml(providerId, ri, null);
|
||||
if (provider != null) {
|
||||
// we might have an inactive entry for this provider already due to
|
||||
// a preceding restore operation. if so, fix it up in place; otherwise
|
||||
// just add this new one.
|
||||
Provider existing = lookupProviderLocked(providerId);
|
||||
// we might have an inactive entry for this provider already due to
|
||||
// a preceding restore operation. if so, fix it up in place; otherwise
|
||||
// just add this new one.
|
||||
Provider existing = lookupProviderLocked(providerId);
|
||||
|
||||
// If the provider was not found it may be because it was restored and
|
||||
// we did not know its UID so let us find if there is such one.
|
||||
if (existing == null) {
|
||||
ProviderId restoredProviderId = new ProviderId(UNKNOWN_UID, componentName);
|
||||
existing = lookupProviderLocked(restoredProviderId);
|
||||
}
|
||||
// If the provider was not found it may be because it was restored and
|
||||
// we did not know its UID so let us find if there is such one.
|
||||
if (existing == null) {
|
||||
ProviderId restoredProviderId = new ProviderId(UNKNOWN_UID, componentName);
|
||||
existing = lookupProviderLocked(restoredProviderId);
|
||||
}
|
||||
|
||||
AppWidgetProviderInfo info = createPartialProviderInfo(providerId, ri, existing);
|
||||
if (info != null) {
|
||||
if (existing != null) {
|
||||
if (existing.zombie && !mSafeMode) {
|
||||
// it's a placeholder that was set up during an app restore
|
||||
existing.id = providerId;
|
||||
existing.zombie = false;
|
||||
existing.info = provider.info; // the real one filled out from the ResolveInfo
|
||||
existing.setPartialInfoLocked(info);
|
||||
if (DEBUG) {
|
||||
Slog.i(TAG, "Provider placeholder now reified: " + existing);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Provider provider = new Provider();
|
||||
provider.id = providerId;
|
||||
provider.setPartialInfoLocked(info);
|
||||
mProviders.add(provider);
|
||||
}
|
||||
return true;
|
||||
@@ -2375,60 +2360,61 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
|
||||
private void sendEnableIntentLocked(Provider p) {
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_ENABLED);
|
||||
intent.setComponent(p.info.provider);
|
||||
sendBroadcastAsUser(intent, p.info.getProfile());
|
||||
intent.setComponent(p.id.componentName);
|
||||
sendBroadcastAsUser(intent, p.id.getProfile());
|
||||
}
|
||||
|
||||
private void sendUpdateIntentLocked(Provider provider, int[] appWidgetIds) {
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
|
||||
intent.setComponent(provider.info.provider);
|
||||
sendBroadcastAsUser(intent, provider.info.getProfile());
|
||||
intent.setComponent(provider.id.componentName);
|
||||
sendBroadcastAsUser(intent, provider.id.getProfile());
|
||||
}
|
||||
|
||||
private void sendDeletedIntentLocked(Widget widget) {
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DELETED);
|
||||
intent.setComponent(widget.provider.info.provider);
|
||||
intent.setComponent(widget.provider.id.componentName);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget.appWidgetId);
|
||||
sendBroadcastAsUser(intent, widget.provider.info.getProfile());
|
||||
sendBroadcastAsUser(intent, widget.provider.id.getProfile());
|
||||
}
|
||||
|
||||
private void sendDisabledIntentLocked(Provider provider) {
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DISABLED);
|
||||
intent.setComponent(provider.info.provider);
|
||||
sendBroadcastAsUser(intent, provider.info.getProfile());
|
||||
intent.setComponent(provider.id.componentName);
|
||||
sendBroadcastAsUser(intent, provider.id.getProfile());
|
||||
}
|
||||
|
||||
public void sendOptionsChangedIntentLocked(Widget widget) {
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED);
|
||||
intent.setComponent(widget.provider.info.provider);
|
||||
intent.setComponent(widget.provider.id.componentName);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget.appWidgetId);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, widget.options);
|
||||
sendBroadcastAsUser(intent, widget.provider.info.getProfile());
|
||||
sendBroadcastAsUser(intent, widget.provider.id.getProfile());
|
||||
}
|
||||
|
||||
private void registerForBroadcastsLocked(Provider provider, int[] appWidgetIds) {
|
||||
if (provider.info.updatePeriodMillis > 0) {
|
||||
AppWidgetProviderInfo info = provider.getInfoLocked(mContext);
|
||||
if (info.updatePeriodMillis > 0) {
|
||||
// if this is the first instance, set the alarm. otherwise,
|
||||
// rely on the fact that we've already set it and that
|
||||
// PendingIntent.getBroadcast will update the extras.
|
||||
boolean alreadyRegistered = provider.broadcast != null;
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
|
||||
intent.setComponent(provider.info.provider);
|
||||
intent.setComponent(info.provider);
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
// Broadcast alarms sent by system are immutable
|
||||
provider.broadcast = PendingIntent.getBroadcastAsUser(mContext, 1, intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE,
|
||||
provider.info.getProfile());
|
||||
info.getProfile());
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
if (!alreadyRegistered) {
|
||||
// Set the alarm outside of our locks; we've latched the first-time
|
||||
// invariant and established the PendingIntent safely.
|
||||
final long period = Math.max(provider.info.updatePeriodMillis, MIN_UPDATE_PERIOD);
|
||||
final long period = Math.max(info.updatePeriodMillis, MIN_UPDATE_PERIOD);
|
||||
final PendingIntent broadcast = provider.broadcast;
|
||||
mSaveStateHandler.post(() ->
|
||||
mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||
@@ -2447,8 +2433,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
return appWidgetIds;
|
||||
}
|
||||
|
||||
private static void dumpProvider(Provider provider, int index, PrintWriter pw) {
|
||||
AppWidgetProviderInfo info = provider.info;
|
||||
private static void dumpProviderLocked(Provider provider, int index, PrintWriter pw) {
|
||||
AppWidgetProviderInfo info = provider.getPartialInfoLocked();
|
||||
pw.print(" ["); pw.print(index); pw.print("] provider ");
|
||||
pw.println(provider.id);
|
||||
pw.print(" min=("); pw.print(info.minWidth);
|
||||
@@ -2467,7 +2453,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
pw.print(Integer.toHexString(info.initialLayout));
|
||||
pw.print(" initialKeyguardLayout=#");
|
||||
pw.print(Integer.toHexString(info.initialKeyguardLayout));
|
||||
pw.print(" zombie="); pw.println(provider.zombie);
|
||||
pw.print(" zombie="); pw.println(provider.zombie);
|
||||
}
|
||||
|
||||
private static void dumpHost(Host host, int index, PrintWriter pw) {
|
||||
@@ -2502,8 +2488,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
|
||||
private static void serializeProvider(TypedXmlSerializer out, Provider p) throws IOException {
|
||||
out.startTag(null, "p");
|
||||
out.attribute(null, "pkg", p.info.provider.getPackageName());
|
||||
out.attribute(null, "cl", p.info.provider.getClassName());
|
||||
out.attribute(null, "pkg", p.id.componentName.getPackageName());
|
||||
out.attribute(null, "cl", p.id.componentName.getClassName());
|
||||
out.attributeIntHex(null, "tag", p.tag);
|
||||
if (!TextUtils.isEmpty(p.infoTag)) {
|
||||
out.attribute(null, "info_tag", p.infoTag);
|
||||
@@ -2604,30 +2590,32 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private Provider parseProviderInfoXml(ProviderId providerId, ResolveInfo ri,
|
||||
Provider oldProvider) {
|
||||
AppWidgetProviderInfo info = null;
|
||||
if (oldProvider != null && !TextUtils.isEmpty(oldProvider.infoTag)) {
|
||||
info = parseAppWidgetProviderInfo(providerId, ri.activityInfo, oldProvider.infoTag);
|
||||
}
|
||||
if (info == null) {
|
||||
info = parseAppWidgetProviderInfo(providerId, ri.activityInfo,
|
||||
AppWidgetManager.META_DATA_APPWIDGET_PROVIDER);
|
||||
}
|
||||
if (info == null) {
|
||||
private AppWidgetProviderInfo createPartialProviderInfo(ProviderId providerId, ResolveInfo ri,
|
||||
Provider provider) {
|
||||
boolean hasXmlDefinition = false;
|
||||
Bundle metaData = ri.activityInfo.metaData;
|
||||
if (metaData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Provider provider = new Provider();
|
||||
provider.id = providerId;
|
||||
provider.info = info;
|
||||
return provider;
|
||||
if (provider != null && !TextUtils.isEmpty(provider.infoTag)) {
|
||||
hasXmlDefinition = metaData.getInt(provider.infoTag) != 0;
|
||||
}
|
||||
hasXmlDefinition |= metaData.getInt(AppWidgetManager.META_DATA_APPWIDGET_PROVIDER) != 0;
|
||||
|
||||
if (hasXmlDefinition) {
|
||||
AppWidgetProviderInfo info = new AppWidgetProviderInfo();
|
||||
info.provider = providerId.componentName;
|
||||
info.providerInfo = ri.activityInfo;
|
||||
return info;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private AppWidgetProviderInfo parseAppWidgetProviderInfo(
|
||||
private static AppWidgetProviderInfo parseAppWidgetProviderInfo(Context context,
|
||||
ProviderId providerId, ActivityInfo activityInfo, String metadataKey) {
|
||||
try (XmlResourceParser parser =
|
||||
activityInfo.loadXmlMetaData(mContext.getPackageManager(), metadataKey)) {
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
try (XmlResourceParser parser = activityInfo.loadXmlMetaData(pm, metadataKey)) {
|
||||
if (parser == null) {
|
||||
Slog.w(TAG, "No " + metadataKey + " meta-data for AppWidget provider '"
|
||||
+ providerId + '\'');
|
||||
@@ -2657,7 +2645,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
final Resources resources;
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final PackageManager pm = mContext.getPackageManager();
|
||||
final int userId = UserHandle.getUserId(providerId.uid);
|
||||
final ApplicationInfo app = pm.getApplicationInfoAsUser(activityInfo.packageName,
|
||||
0, userId);
|
||||
@@ -2696,7 +2683,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
info.configure = new ComponentName(providerId.componentName.getPackageName(),
|
||||
className);
|
||||
}
|
||||
info.label = activityInfo.loadLabel(mContext.getPackageManager()).toString();
|
||||
info.label = activityInfo.loadLabel(pm).toString();
|
||||
info.icon = activityInfo.getIconResource();
|
||||
info.previewImage = sa.getResourceId(
|
||||
com.android.internal.R.styleable.AppWidgetProviderInfo_previewImage, 0);
|
||||
@@ -2821,7 +2808,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
|
||||
if (provider.widgets.size() > 0) {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
|
||||
"appwidget init " + provider.info.provider.getPackageName());
|
||||
"appwidget init " + provider.id.componentName.getPackageName());
|
||||
sendEnableIntentLocked(provider);
|
||||
int[] appWidgetIds = getWidgetIds(provider.widgets);
|
||||
sendUpdateIntentLocked(provider, appWidgetIds);
|
||||
@@ -2949,7 +2936,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
if (packages == null) {
|
||||
mWidgetPackages.put(userId, packages = new ArraySet<String>());
|
||||
}
|
||||
packages.add(widget.provider.info.provider.getPackageName());
|
||||
packages.add(widget.provider.id.componentName.getPackageName());
|
||||
}
|
||||
|
||||
// If we are adding a widget it might be for a provider that
|
||||
@@ -2976,7 +2963,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
if (widget.provider == null) return;
|
||||
|
||||
final int userId = widget.provider.getUserId();
|
||||
final String packageName = widget.provider.info.provider.getPackageName();
|
||||
final String packageName = widget.provider.id.componentName.getPackageName();
|
||||
synchronized (mWidgetPackagesLock) {
|
||||
ArraySet<String> packages = mWidgetPackages.get(userId);
|
||||
if (packages == null) {
|
||||
@@ -2989,7 +2976,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
Widget w = mWidgets.get(i);
|
||||
if (w.provider == null) continue;
|
||||
if (w.provider.getUserId() == userId
|
||||
&& packageName.equals(w.provider.info.provider.getPackageName())) {
|
||||
&& packageName.equals(w.provider.id.componentName.getPackageName())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3185,10 +3172,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
|
||||
if (provider == null && mSafeMode) {
|
||||
// if we're in safe mode, make a temporary one
|
||||
AppWidgetProviderInfo info = new AppWidgetProviderInfo();
|
||||
info.provider = providerId.componentName;
|
||||
info.providerInfo = providerInfo;
|
||||
|
||||
provider = new Provider();
|
||||
provider.info = new AppWidgetProviderInfo();
|
||||
provider.info.provider = providerId.componentName;
|
||||
provider.info.providerInfo = providerInfo;
|
||||
provider.setPartialInfoLocked(info);
|
||||
provider.zombie = true;
|
||||
provider.id = providerId;
|
||||
mProviders.add(provider);
|
||||
@@ -3197,15 +3186,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
final int providerTag = parser.getAttributeIntHex(null, "tag",
|
||||
legacyProviderIndex);
|
||||
provider.tag = providerTag;
|
||||
|
||||
provider.infoTag = parser.getAttributeValue(null, "info_tag");
|
||||
if (!TextUtils.isEmpty(provider.infoTag) && !mSafeMode) {
|
||||
AppWidgetProviderInfo info = parseAppWidgetProviderInfo(
|
||||
providerId, providerInfo, provider.infoTag);
|
||||
if (info != null) {
|
||||
provider.info = info;
|
||||
}
|
||||
}
|
||||
} else if ("h".equals(tag)) {
|
||||
legacyHostIndex++;
|
||||
Host host = new Host();
|
||||
@@ -3426,11 +3407,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
providersUpdated = true;
|
||||
}
|
||||
} else {
|
||||
Provider parsed = parseProviderInfoXml(providerId, ri, provider);
|
||||
if (parsed != null) {
|
||||
AppWidgetProviderInfo info =
|
||||
createPartialProviderInfo(providerId, ri, provider);
|
||||
if (info != null) {
|
||||
keep.add(providerId);
|
||||
// Use the new AppWidgetProviderInfo.
|
||||
provider.info = parsed.info;
|
||||
provider.setPartialInfoLocked(info);
|
||||
// If it's enabled
|
||||
final int M = provider.widgets.size();
|
||||
if (M > 0) {
|
||||
@@ -3460,7 +3442,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
N = mProviders.size();
|
||||
for (int i = N - 1; i >= 0; i--) {
|
||||
Provider provider = mProviders.get(i);
|
||||
if (packageName.equals(provider.info.provider.getPackageName())
|
||||
if (packageName.equals(provider.id.componentName.getPackageName())
|
||||
&& provider.getUserId() == userId
|
||||
&& !keep.contains(provider.id)) {
|
||||
if (removedProviders != null) {
|
||||
@@ -3479,7 +3461,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
final int N = mProviders.size();
|
||||
for (int i = 0; i < N; ++i) {
|
||||
Provider provider = mProviders.get(i);
|
||||
if (pkgName.equals(provider.info.provider.getPackageName())
|
||||
if (pkgName.equals(provider.id.componentName.getPackageName())
|
||||
&& provider.getUserId() == userId
|
||||
&& provider.widgets.size() > 0) {
|
||||
deleteWidgetsLocked(provider, parentUserId);
|
||||
@@ -3493,7 +3475,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
final int N = mProviders.size();
|
||||
for (int i = N - 1; i >= 0; i--) {
|
||||
Provider provider = mProviders.get(i);
|
||||
if (pkgName.equals(provider.info.provider.getPackageName())
|
||||
if (pkgName.equals(provider.id.componentName.getPackageName())
|
||||
&& provider.getUserId() == userId) {
|
||||
deleteProviderLocked(provider);
|
||||
removed = true;
|
||||
@@ -3972,17 +3954,21 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
}
|
||||
|
||||
private static final class Provider {
|
||||
|
||||
ProviderId id;
|
||||
AppWidgetProviderInfo info;
|
||||
ArrayList<Widget> widgets = new ArrayList<>();
|
||||
PendingIntent broadcast;
|
||||
String infoTag;
|
||||
|
||||
boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
|
||||
|
||||
boolean maskedByLockedProfile;
|
||||
boolean maskedByQuietProfile;
|
||||
boolean maskedBySuspendedPackage;
|
||||
|
||||
boolean mInfoParsed = false;
|
||||
|
||||
int tag = TAG_UNDEFINED; // for use while saving state (the index)
|
||||
|
||||
public int getUserId() {
|
||||
@@ -4007,6 +3993,51 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
return false;
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
public AppWidgetProviderInfo getInfoLocked(Context context) {
|
||||
if (!mInfoParsed) {
|
||||
// parse
|
||||
if (!zombie) {
|
||||
AppWidgetProviderInfo newInfo = null;
|
||||
if (!TextUtils.isEmpty(infoTag)) {
|
||||
newInfo = parseAppWidgetProviderInfo(
|
||||
context, id, info.providerInfo, infoTag);
|
||||
}
|
||||
if (newInfo == null) {
|
||||
newInfo = parseAppWidgetProviderInfo(context, id, info.providerInfo,
|
||||
AppWidgetManager.META_DATA_APPWIDGET_PROVIDER);
|
||||
}
|
||||
if (newInfo != null) {
|
||||
info = newInfo;
|
||||
}
|
||||
}
|
||||
mInfoParsed = true;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last updated AppWidgetProviderInfo for this provider. This info may not
|
||||
* be completely parsed and only contain placeHolder information like
|
||||
* {@link AppWidgetProviderInfo#providerInfo}
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
public AppWidgetProviderInfo getPartialInfoLocked() {
|
||||
return info;
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
public void setPartialInfoLocked(AppWidgetProviderInfo info) {
|
||||
this.info = info;
|
||||
mInfoParsed = false;
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
public void setInfoLocked(AppWidgetProviderInfo info) {
|
||||
this.info = info;
|
||||
mInfoParsed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Provider{" + id + (zombie ? " Z" : "") + '}';
|
||||
@@ -4051,6 +4082,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
this.componentName = componentName;
|
||||
}
|
||||
|
||||
public UserHandle getProfile() {
|
||||
return UserHandle.getUserHandleForUid(uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
@@ -4116,8 +4151,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
final int N = widgets.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
Provider provider = widgets.get(i).provider;
|
||||
if (provider != null && provider.getUserId() == userId && provider.info != null
|
||||
&& pkg.equals(provider.info.provider.getPackageName())) {
|
||||
if (provider != null && provider.getUserId() == userId
|
||||
&& pkg.equals(provider.id.componentName.getPackageName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4127,7 +4162,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
/**
|
||||
* Adds all pending updates in {@param outUpdates} keys by the update time.
|
||||
*/
|
||||
public void getPendingUpdatesForId(int appWidgetId,
|
||||
public void getPendingUpdatesForIdLocked(Context context, int appWidgetId,
|
||||
LongSparseArray<PendingHostUpdate> outUpdates) {
|
||||
long updateSequenceNo = lastWidgetUpdateSequenceNo;
|
||||
int N = widgets.size();
|
||||
@@ -4144,7 +4179,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
switch (id) {
|
||||
case ID_PROVIDER_CHANGED:
|
||||
update = PendingHostUpdate.providerChanged(
|
||||
appWidgetId, widget.provider.info);
|
||||
appWidgetId, widget.provider.getInfoLocked(context));
|
||||
break;
|
||||
case ID_VIEWS_UPDATE:
|
||||
update = PendingHostUpdate.updateAppWidget(appWidgetId,
|
||||
@@ -4493,10 +4528,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
|
||||
Provider p = findProviderLocked(componentName, userId);
|
||||
if (p == null) {
|
||||
AppWidgetProviderInfo info = new AppWidgetProviderInfo();
|
||||
info.provider = componentName;
|
||||
|
||||
p = new Provider();
|
||||
p.id = new ProviderId(UNKNOWN_UID, componentName);
|
||||
p.info = new AppWidgetProviderInfo();
|
||||
p.info.provider = componentName;
|
||||
p.setPartialInfoLocked(info);
|
||||
p.zombie = true;
|
||||
mProviders.add(p);
|
||||
}
|
||||
@@ -4561,7 +4598,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
}
|
||||
addWidgetLocked(id);
|
||||
}
|
||||
if (id.provider != null && id.provider.info != null) {
|
||||
if (id.provider != null
|
||||
&& id.provider.getPartialInfoLocked() != null) {
|
||||
stashProviderRestoreUpdateLocked(id.provider,
|
||||
restoredId, id.appWidgetId);
|
||||
} else {
|
||||
@@ -4787,7 +4825,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS, oldIds);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, newIds);
|
||||
if (provider != null) {
|
||||
intent.setComponent(provider.info.provider);
|
||||
intent.setComponent(provider.id.componentName);
|
||||
sendBroadcastAsUser(intent, userHandle);
|
||||
}
|
||||
if (host != null) {
|
||||
|
||||
Reference in New Issue
Block a user