Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48032682 authored by Hui Yu's avatar Hui Yu
Browse files

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
parent 4d7fb0b4
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -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));
            }
        };
    }
}
+4 −4
Original line number Diff line number Diff line
@@ -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();
        }
+1 −12
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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);
}
+19 −28
Original line number Diff line number Diff line
@@ -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);
            synchronized (mLock) {
                final Widget widget = lookupWidgetLocked(appWidgetId, callingUid, callingPackage);
                if (widget == null) {
                    return;
                }
            // The callingUid must be default launcher uid.
            if (defaultLauncherUid != callingUid) {
                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(uid, packageName);
                uid2PackageName.put(providerId.uid, packageName);
                mAppOpsManagerInternal.updateAppWidgetVisibility(uid2PackageName, true);
            mUsageStatsManagerInternal.reportEvent(packageName, UserHandle.getUserId(uid),
                    UsageEvents.Event.USER_INTERACTION);
                mUsageStatsManagerInternal.reportEvent(packageName,
                        UserHandle.getUserId(providerId.uid), UsageEvents.Event.USER_INTERACTION);
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
Loading