Merge "Update AppOps & UsageStats when app widget tapped." into rvc-dev
This commit is contained in:
@@ -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_START;
|
||||||
import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_STOP;
|
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.ROLLOVER_FOREGROUND_SERVICE;
|
||||||
|
import static android.app.usage.UsageEvents.Event.USER_INTERACTION;
|
||||||
|
|
||||||
import android.annotation.SystemApi;
|
import android.annotation.SystemApi;
|
||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
@@ -580,6 +581,18 @@ public final class UsageStats implements Parcelable {
|
|||||||
incrementServiceTimeUsed(timeStamp);
|
incrementServiceTimeUsed(timeStamp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case USER_INTERACTION:
|
||||||
|
if (hasForegroundActivity()) {
|
||||||
|
incrementTimeUsed(timeStamp);
|
||||||
|
} else {
|
||||||
|
mLastTimeUsed = timeStamp;
|
||||||
|
}
|
||||||
|
if (hasVisibleActivity()) {
|
||||||
|
incrementTimeVisible(timeStamp);
|
||||||
|
} else {
|
||||||
|
mLastTimeVisible = timeStamp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1240,4 +1240,18 @@ public class AppWidgetManager {
|
|||||||
throw e.rethrowFromSystemServer();
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import android.app.Application;
|
|||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.RemoteInput;
|
import android.app.RemoteInput;
|
||||||
import android.appwidget.AppWidgetHostView;
|
import android.appwidget.AppWidgetHostView;
|
||||||
|
import android.appwidget.AppWidgetManager;
|
||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.ContextWrapper;
|
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 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
|
// the call to startIntentSender() to ensure that they are consistently applied to
|
||||||
// both mutable and immutable PendingIntents.
|
// 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(
|
context.startIntentSender(
|
||||||
pendingIntent.getIntentSender(), options.first,
|
intentSender, options.first,
|
||||||
0, 0, 0, options.second.toBundle());
|
0, 0, 0, options.second.toBundle());
|
||||||
} catch (IntentSender.SendIntentException e) {
|
} catch (IntentSender.SendIntentException e) {
|
||||||
Log.e(LOG_TAG, "Cannot send pending intent: ", e);
|
Log.e(LOG_TAG, "Cannot send pending intent: ", e);
|
||||||
|
|||||||
@@ -77,5 +77,6 @@ interface IAppWidgetService {
|
|||||||
boolean requestPinAppWidget(String packageName, in ComponentName providerComponent,
|
boolean requestPinAppWidget(String packageName, in ComponentName providerComponent,
|
||||||
in Bundle extras, in IntentSender resultIntent);
|
in Bundle extras, in IntentSender resultIntent);
|
||||||
boolean isRequestPinAppWidgetSupported();
|
boolean isRequestPinAppWidgetSupported();
|
||||||
|
void noteAppWidgetTapped(int uid, String packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ import android.app.KeyguardManager;
|
|||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.admin.DevicePolicyManagerInternal;
|
import android.app.admin.DevicePolicyManagerInternal;
|
||||||
import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener;
|
import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener;
|
||||||
|
import android.app.usage.UsageEvents;
|
||||||
|
import android.app.usage.UsageStatsManagerInternal;
|
||||||
import android.appwidget.AppWidgetManager;
|
import android.appwidget.AppWidgetManager;
|
||||||
import android.appwidget.AppWidgetManagerInternal;
|
import android.appwidget.AppWidgetManagerInternal;
|
||||||
import android.appwidget.AppWidgetProviderInfo;
|
import android.appwidget.AppWidgetProviderInfo;
|
||||||
@@ -235,6 +237,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
|||||||
private PackageManagerInternal mPackageManagerInternal;
|
private PackageManagerInternal mPackageManagerInternal;
|
||||||
private ActivityManagerInternal mActivityManagerInternal;
|
private ActivityManagerInternal mActivityManagerInternal;
|
||||||
private AppOpsManagerInternal mAppOpsManagerInternal;
|
private AppOpsManagerInternal mAppOpsManagerInternal;
|
||||||
|
private UsageStatsManagerInternal mUsageStatsManagerInternal;
|
||||||
|
|
||||||
private SecurityPolicy mSecurityPolicy;
|
private SecurityPolicy mSecurityPolicy;
|
||||||
|
|
||||||
@@ -278,6 +281,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
|||||||
void systemServicesReady() {
|
void systemServicesReady() {
|
||||||
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
|
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
|
||||||
mAppOpsManagerInternal = LocalServices.getService(AppOpsManagerInternal.class);
|
mAppOpsManagerInternal = LocalServices.getService(AppOpsManagerInternal.class);
|
||||||
|
mUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeMaximumWidgetBitmapMemory() {
|
private void computeMaximumWidgetBitmapMemory() {
|
||||||
@@ -879,8 +883,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
|||||||
outUpdates.add(updatesMap.valueAt(j));
|
outUpdates.add(updatesMap.valueAt(j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateAppOpsLocked(host, true);
|
|
||||||
|
|
||||||
// Reset the update counter once all the updates have been calculated
|
// Reset the update counter once all the updates have been calculated
|
||||||
host.lastWidgetUpdateSequenceNo = updateSequenceNo;
|
host.lastWidgetUpdateSequenceNo = updateSequenceNo;
|
||||||
return new ParceledListSlice<>(outUpdates);
|
return new ParceledListSlice<>(outUpdates);
|
||||||
@@ -909,7 +911,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
|||||||
if (host != null) {
|
if (host != null) {
|
||||||
host.callbacks = null;
|
host.callbacks = null;
|
||||||
pruneHostLocked(host);
|
pruneHostLocked(host);
|
||||||
updateAppOpsLocked(host, false);
|
mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUids(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3646,26 +3648,49 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAppOpsLocked(Host host, boolean visible) {
|
/**
|
||||||
if (visible) {
|
* Note an app widget is tapped on. If a app widget is tapped, the underlying app is treated as
|
||||||
final int procState = mActivityManagerInternal.getUidProcessState(host.id.uid);
|
* 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) {
|
if (procState > ActivityManager.PROCESS_STATE_TOP) {
|
||||||
// The launcher must be at TOP.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
final List<ResolveInfo> allHomeCandidates = new ArrayList<>();
|
// Default launcher from package manager.
|
||||||
// Default launcher from package manager.
|
final ComponentName defaultLauncher = mPackageManagerInternal
|
||||||
final ComponentName defaultLauncher = mPackageManagerInternal
|
.getDefaultHomeActivity(UserHandle.getUserId(callingUid));
|
||||||
.getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getUserId(host.id.uid));
|
int defaultLauncherUid = 0;
|
||||||
// The launcher must be default launcher.
|
try {
|
||||||
if (defaultLauncher == null
|
defaultLauncherUid = mPackageManager.getApplicationInfo(
|
||||||
|| !defaultLauncher.getPackageName().equals(host.id.packageName)) {
|
defaultLauncher.getPackageName(), 0 ,
|
||||||
return;
|
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 {
|
private final class CallbackHandler extends Handler {
|
||||||
|
|||||||
Reference in New Issue
Block a user