summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/usage/UsageStats.java13
-rw-r--r--core/java/android/appwidget/AppWidgetManager.java14
-rw-r--r--core/java/android/widget/RemoteViews.java13
-rw-r--r--core/java/com/android/internal/appwidget/IAppWidgetService.aidl1
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java61
5 files changed, 83 insertions, 19 deletions
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
index d06baed1a35d..4d73a61c972d 100644
--- a/core/java/android/app/usage/UsageStats.java
+++ b/core/java/android/app/usage/UsageStats.java
@@ -27,6 +27,7 @@ import static android.app.usage.UsageEvents.Event.FLUSH_TO_DISK;
import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_START;
import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_STOP;
import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE;
+import static android.app.usage.UsageEvents.Event.USER_INTERACTION;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -580,6 +581,18 @@ public final class UsageStats implements Parcelable {
incrementServiceTimeUsed(timeStamp);
}
break;
+ case USER_INTERACTION:
+ if (hasForegroundActivity()) {
+ incrementTimeUsed(timeStamp);
+ } else {
+ mLastTimeUsed = timeStamp;
+ }
+ if (hasVisibleActivity()) {
+ incrementTimeVisible(timeStamp);
+ } else {
+ mLastTimeVisible = timeStamp;
+ }
+ break;
default:
break;
}
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 0d461f5fa32c..844128758d7c 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -1240,4 +1240,18 @@ public class AppWidgetManager {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Note an app widget is tapped on.
+ * @param uid App UID.
+ * @param packageName App package name.
+ * @hide
+ */
+ public void noteAppWidgetTapped(int uid, @NonNull String packageName) {
+ try {
+ mService.noteAppWidgetTapped(uid, packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 7f6c0d2077f1..4a27d3a0e71d 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -29,6 +29,7 @@ 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;
@@ -4130,8 +4131,18 @@ 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(
- pendingIntent.getIntentSender(), options.first,
+ intentSender, 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 6d1d1abd1ec4..9e09cf35bfec 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -77,5 +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);
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 260703db190c..8c1360cca940 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -35,6 +35,8 @@ import android.app.KeyguardManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManagerInternal;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetManagerInternal;
import android.appwidget.AppWidgetProviderInfo;
@@ -235,6 +237,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
private PackageManagerInternal mPackageManagerInternal;
private ActivityManagerInternal mActivityManagerInternal;
private AppOpsManagerInternal mAppOpsManagerInternal;
+ private UsageStatsManagerInternal mUsageStatsManagerInternal;
private SecurityPolicy mSecurityPolicy;
@@ -278,6 +281,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
void systemServicesReady() {
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mAppOpsManagerInternal = LocalServices.getService(AppOpsManagerInternal.class);
+ mUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class);
}
private void computeMaximumWidgetBitmapMemory() {
@@ -879,8 +883,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
outUpdates.add(updatesMap.valueAt(j));
}
}
- updateAppOpsLocked(host, true);
-
// Reset the update counter once all the updates have been calculated
host.lastWidgetUpdateSequenceNo = updateSequenceNo;
return new ParceledListSlice<>(outUpdates);
@@ -909,7 +911,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
if (host != null) {
host.callbacks = null;
pruneHostLocked(host);
- updateAppOpsLocked(host, false);
+ mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUids(), false);
}
}
}
@@ -3646,26 +3648,49 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
return false;
}
- private void updateAppOpsLocked(Host host, boolean visible) {
- if (visible) {
- final int procState = mActivityManagerInternal.getUidProcessState(host.id.uid);
+ /**
+ * 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.
+ */
+ @Override
+ public void noteAppWidgetTapped(int uid, String packageName) {
+ final int callingUid = Binder.getCallingUid();
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ // The launcher must be at TOP.
+ final int procState = mActivityManagerInternal.getUidProcessState(callingUid);
if (procState > ActivityManager.PROCESS_STATE_TOP) {
- // The launcher must be at TOP.
return;
}
- }
- final List<ResolveInfo> allHomeCandidates = new ArrayList<>();
- // Default launcher from package manager.
- final ComponentName defaultLauncher = mPackageManagerInternal
- .getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getUserId(host.id.uid));
- // The launcher must be default launcher.
- if (defaultLauncher == null
- || !defaultLauncher.getPackageName().equals(host.id.packageName)) {
- return;
+ // Default launcher from package manager.
+ final ComponentName defaultLauncher = mPackageManagerInternal
+ .getDefaultHomeActivity(UserHandle.getUserId(callingUid));
+ 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;
+ }
+ 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);
}
-
- mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUids(), visible);
}
private final class CallbackHandler extends Handler {