diff options
author | Hui Yu <huiyu@google.com> | 2020-04-10 14:18:51 -0700 |
---|---|---|
committer | Hui Yu <huiyu@google.com> | 2020-04-15 22:06:12 -0700 |
commit | 48032682297d848754ded3b157044bbc4e22db71 (patch) | |
tree | 7a708dcee8b4b6b761bace7cd89c2c17598439e5 | |
parent | 4d7fb0b4c24d1e3be98b824497edc207498a0a81 (diff) |
Move noteAppWidgetTapped call into AppWidgetHostView.
RemoteViews is public API used out of scope of widget. The correct place
to call noteAppWidgetTapped is in AppWidgetHostView.
Fix: 153676411
Test: manual test, tap a widget, "adb shell dumpsys usagestats | grep
USER_INTERACTION" to oberserve USER_INTERACTION event sent to UsageStas, "adb shell dumpsys appops | grep appWidgetVisible" to observer appWidgetVisible flag.
Change-Id: Ic473211b91fd952dbb81b09b1e1568d6f69a0dd8
6 files changed, 45 insertions, 48 deletions
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 09d56ec70e56..75ce0dcc1d1d 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -104,7 +104,7 @@ public class AppWidgetHostView extends FrameLayout { */ public AppWidgetHostView(Context context, OnClickHandler handler) { this(context, android.R.anim.fade_in, android.R.anim.fade_out); - mOnClickHandler = handler; + mOnClickHandler = getHandler(handler); } /** @@ -131,7 +131,7 @@ public class AppWidgetHostView extends FrameLayout { * @hide */ public void setOnClickHandler(OnClickHandler handler) { - mOnClickHandler = handler; + mOnClickHandler = getHandler(handler); } /** @@ -423,7 +423,6 @@ public class AppWidgetHostView extends FrameLayout { // inflate any requested LayoutParams. mRemoteContext = getRemoteContext(); int layoutId = remoteViews.getLayoutId(); - // If our stale view has been prepared to match active, and the new // layout matches, try recycling it if (content == null && layoutId == mLayoutId) { @@ -711,4 +710,16 @@ public class AppWidgetHostView extends FrameLayout { } return null; } + + private OnClickHandler getHandler(OnClickHandler handler) { + return (view, pendingIntent, response) -> { + AppWidgetManager.getInstance(mContext).noteAppWidgetTapped(mAppWidgetId); + if (handler != null) { + return handler.onClickHandler(view, pendingIntent, response); + } else { + return RemoteViews.startPendingIntent(view, pendingIntent, + response.getLaunchOptions(view)); + } + }; + } } diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java index 844128758d7c..009ec522e436 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -1243,13 +1243,13 @@ public class AppWidgetManager { /** * Note an app widget is tapped on. - * @param uid App UID. - * @param packageName App package name. + * + * @param appWidgetId App widget id. * @hide */ - public void noteAppWidgetTapped(int uid, @NonNull String packageName) { + public void noteAppWidgetTapped(int appWidgetId) { try { - mService.noteAppWidgetTapped(uid, packageName); + mService.noteAppWidgetTapped(mPackageName, appWidgetId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 4a27d3a0e71d..7f6c0d2077f1 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -29,7 +29,6 @@ import android.app.Application; import android.app.PendingIntent; import android.app.RemoteInput; import android.appwidget.AppWidgetHostView; -import android.appwidget.AppWidgetManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.ContextWrapper; @@ -4131,18 +4130,8 @@ public class RemoteViews implements Parcelable, Filter { // The NEW_TASK flags are applied through the activity options and not as a part of // the call to startIntentSender() to ensure that they are consistently applied to // both mutable and immutable PendingIntents. - final IntentSender intentSender = pendingIntent.getIntentSender(); - final int uid = intentSender.getCreatorUid(); - final String packageName = intentSender.getCreatorPackage(); - if (uid != -1 && packageName != null) { - final AppWidgetManager appWidgetManager = - context.getSystemService(AppWidgetManager.class); - if (appWidgetManager != null) { - appWidgetManager.noteAppWidgetTapped(uid, packageName); - } - } context.startIntentSender( - intentSender, options.first, + pendingIntent.getIntentSender(), options.first, 0, 0, 0, options.second.toBundle()); } catch (IntentSender.SendIntentException e) { Log.e(LOG_TAG, "Cannot send pending intent: ", e); diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl index 9e09cf35bfec..1186dfe92906 100644 --- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl +++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl @@ -77,6 +77,6 @@ interface IAppWidgetService { boolean requestPinAppWidget(String packageName, in ComponentName providerComponent, in Bundle extras, in IntentSender resultIntent); boolean isRequestPinAppWidgetSupported(); - void noteAppWidgetTapped(int uid, String packageName); + oneway void noteAppWidgetTapped(in String callingPackage, in int appWidgetId); } diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index ca1b27bd261e..74e4e4a43126 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -3652,11 +3652,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku * Note an app widget is tapped on. If a app widget is tapped, the underlying app is treated as * foreground so the app can get while-in-use permission. * - * @param uid UID of the underlying app. - * @param packageName Package name of the app. + * @param callingPackage calling app's packageName. + * @param appWidgetId App widget id. */ @Override - public void noteAppWidgetTapped(int uid, String packageName) { + public void noteAppWidgetTapped(String callingPackage, int appWidgetId) { + mSecurityPolicy.enforceCallFromPackage(callingPackage); final int callingUid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { @@ -3665,32 +3666,22 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku if (procState > ActivityManager.PROCESS_STATE_TOP) { return; } - - // Default launcher from package manager. - final ComponentName defaultLauncher = mPackageManagerInternal - .getDefaultHomeActivity(UserHandle.getUserId(callingUid)); - if (defaultLauncher == null) { - return; - } - int defaultLauncherUid = 0; - try { - defaultLauncherUid = mPackageManager.getApplicationInfo( - defaultLauncher.getPackageName(), 0 , - UserHandle.getUserId(callingUid)).uid; - } catch (RemoteException e) { - Slog.e(TAG, "Failed to getApplicationInfo for package:" - + defaultLauncher.getPackageName(), e); - return; - } - // The callingUid must be default launcher uid. - if (defaultLauncherUid != callingUid) { - return; + synchronized (mLock) { + final Widget widget = lookupWidgetLocked(appWidgetId, callingUid, callingPackage); + if (widget == null) { + return; + } + final ProviderId providerId = widget.provider.id; + final String packageName = providerId.componentName.getPackageName(); + if (packageName == null) { + return; + } + final SparseArray<String> uid2PackageName = new SparseArray<String>(); + uid2PackageName.put(providerId.uid, packageName); + mAppOpsManagerInternal.updateAppWidgetVisibility(uid2PackageName, true); + mUsageStatsManagerInternal.reportEvent(packageName, + UserHandle.getUserId(providerId.uid), UsageEvents.Event.USER_INTERACTION); } - final SparseArray<String> uid2PackageName = new SparseArray<String>(); - uid2PackageName.put(uid, packageName); - mAppOpsManagerInternal.updateAppWidgetVisibility(uid2PackageName, true); - mUsageStatsManagerInternal.reportEvent(packageName, UserHandle.getUserId(uid), - UsageEvents.Event.USER_INTERACTION); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 31bcceaba889..1ef269cb2cf8 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -5309,6 +5309,12 @@ public class AppOpsService extends IAppOpsService.Stub { pw.print(" pendingCapability="); pw.println(uidState.pendingCapability); } + pw.print(" appWidgetVisible="); + pw.println(uidState.appWidgetVisible); + if (uidState.appWidgetVisible != uidState.pendingAppWidgetVisible) { + pw.print(" pendingAppWidgetVisible="); + pw.println(uidState.pendingAppWidgetVisible); + } if (uidState.pendingStateCommitTime != 0) { pw.print(" pendingStateCommitTime="); TimeUtils.formatDuration(uidState.pendingStateCommitTime, nowElapsed, pw); |