Merge "Implement dark launch logic for sharesheet aiai model." into sc-dev

This commit is contained in:
TreeHugger Robot
2021-03-22 17:45:13 +00:00
committed by Android (Google) Code Review
9 changed files with 112 additions and 15 deletions

View File

@@ -414,6 +414,12 @@ public final class SystemUiDeviceConfigFlags {
*/
public static final String CHOOSER_TARGET_RANKING_ENABLED = "chooser_target_ranking_enabled";
/**
* (boolean) Whether dark launch of remote prediction service is enabled.
*/
public static final String DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED =
"dark_launch_remote_prediction_service_enabled";
/**
* (boolean) Whether to enable pinch resizing for PIP.
*/

View File

@@ -35,6 +35,7 @@ import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.os.Binder;
import android.os.IBinder;
import android.os.Process;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.util.Slog;
@@ -179,7 +180,8 @@ public class AppPredictionManagerService extends
Context ctx = getContext();
if (!(ctx.checkCallingPermission(PACKAGE_USAGE_STATS) == PERMISSION_GRANTED
|| mServiceNameResolver.isTemporary(userId)
|| mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid()))) {
|| mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())
|| Binder.getCallingUid() == Process.SYSTEM_UID)) {
String msg = "Permission Denial: " + func + " from pid="
+ Binder.getCallingPid()

View File

@@ -40,6 +40,7 @@ import android.util.ArrayMap;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.infra.AbstractRemoteService;
import com.android.server.LocalServices;
import com.android.server.infra.AbstractPerUserSystemService;
@@ -55,6 +56,8 @@ public class AppPredictionPerUserService extends
private static final String TAG = AppPredictionPerUserService.class.getSimpleName();
private static final String PREDICT_USING_PEOPLE_SERVICE_PREFIX =
"predict_using_people_service_";
private static final String REMOTE_APP_PREDICTOR_KEY = "remote_app_predictor";
@Nullable
@GuardedBy("mLock")
@@ -112,8 +115,16 @@ public class AppPredictionPerUserService extends
@GuardedBy("mLock")
public void onCreatePredictionSessionLocked(@NonNull AppPredictionContext context,
@NonNull AppPredictionSessionId sessionId, @NonNull IBinder token) {
final boolean usesPeopleService = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
boolean usesPeopleService = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
PREDICT_USING_PEOPLE_SERVICE_PREFIX + context.getUiSurface(), false);
if (context.getExtras() != null
&& context.getExtras().getBoolean(REMOTE_APP_PREDICTOR_KEY, false)
&& DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED, false)
) {
// connect with remote AppPredictionService instead for dark launch
usesPeopleService = false;
}
final boolean serviceExists = resolveService(sessionId, false,
usesPeopleService, s -> s.onCreatePredictionSession(context, sessionId));
if (serviceExists && !mSessionInfos.containsKey(sessionId)) {

View File

@@ -388,9 +388,11 @@ public class PeopleService extends SystemService {
private Map<AppPredictionSessionId, SessionInfo> mSessions = new ArrayMap<>();
@Override
public void onCreatePredictionSession(AppPredictionContext context,
public void onCreatePredictionSession(AppPredictionContext appPredictionContext,
AppPredictionSessionId sessionId) {
mSessions.put(sessionId, new SessionInfo(context, mDataManager, sessionId.getUserId()));
mSessions.put(sessionId,
new SessionInfo(appPredictionContext, mDataManager, sessionId.getUserId(),
getContext()));
}
@Override

View File

@@ -20,6 +20,7 @@ import android.annotation.UserIdInt;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppTarget;
import android.app.prediction.IPredictionCallback;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -40,9 +41,9 @@ class SessionInfo {
new RemoteCallbackList<>();
SessionInfo(AppPredictionContext predictionContext, DataManager dataManager,
@UserIdInt int callingUserId) {
@UserIdInt int callingUserId, Context context) {
mAppTargetPredictor = AppTargetPredictor.create(predictionContext,
this::updatePredictions, dataManager, callingUserId);
this::updatePredictions, dataManager, callingUserId, context);
}
void addCallback(IPredictionCallback callback) {

View File

@@ -24,6 +24,7 @@ import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetEvent;
import android.app.prediction.AppTargetId;
import android.content.Context;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.people.data.DataManager;
@@ -43,10 +44,10 @@ public class AppTargetPredictor {
/** Creates a {@link AppTargetPredictor} instance based on the prediction context. */
public static AppTargetPredictor create(@NonNull AppPredictionContext predictionContext,
@NonNull Consumer<List<AppTarget>> updatePredictionsMethod,
@NonNull DataManager dataManager, @UserIdInt int callingUserId) {
@NonNull DataManager dataManager, @UserIdInt int callingUserId, Context context) {
if (UI_SURFACE_SHARE.equals(predictionContext.getUiSurface())) {
return new ShareTargetPredictor(
predictionContext, updatePredictionsMethod, dataManager, callingUserId);
return new ShareTargetPredictor(predictionContext, updatePredictionsMethod, dataManager,
callingUserId, context);
}
return new AppTargetPredictor(
predictionContext, updatePredictionsMethod, dataManager, callingUserId);
@@ -124,6 +125,11 @@ public class AppTargetPredictor {
callback.accept(targets);
}
/** To be overridden by the subclass to recycle resources. */
@WorkerThread
void destroy() {
}
AppPredictionContext getPredictionContext() {
return mPredictionContext;
}

View File

@@ -16,6 +16,8 @@
package com.android.server.people.prediction;
import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
import static java.util.Collections.reverseOrder;
import android.annotation.NonNull;
@@ -23,17 +25,23 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionManager;
import android.app.prediction.AppPredictor;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetEvent;
import android.app.prediction.AppTargetId;
import android.content.Context;
import android.content.IntentFilter;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager.ShareShortcutInfo;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.Log;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ChooserActivity;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.server.people.data.ConversationInfo;
import com.android.server.people.data.DataManager;
import com.android.server.people.data.EventHistory;
@@ -52,14 +60,27 @@ class ShareTargetPredictor extends AppTargetPredictor {
private static final String TAG = "ShareTargetPredictor";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final String REMOTE_APP_PREDICTOR_KEY = "remote_app_predictor";
private final IntentFilter mIntentFilter;
private final AppPredictor mRemoteAppPredictor;
ShareTargetPredictor(@NonNull AppPredictionContext predictionContext,
@NonNull Consumer<List<AppTarget>> updatePredictionsMethod,
@NonNull DataManager dataManager, @UserIdInt int callingUserId) {
@NonNull DataManager dataManager,
@UserIdInt int callingUserId, @NonNull Context context) {
super(predictionContext, updatePredictionsMethod, dataManager, callingUserId);
mIntentFilter = predictionContext.getExtras().getParcelable(
ChooserActivity.APP_PREDICTION_INTENT_FILTER_KEY);
if (DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED,
false)) {
predictionContext.getExtras().putBoolean(REMOTE_APP_PREDICTOR_KEY, true);
mRemoteAppPredictor = context.createContextAsUser(UserHandle.of(callingUserId), 0)
.getSystemService(AppPredictionManager.class)
.createAppPredictionSession(predictionContext);
} else {
mRemoteAppPredictor = null;
}
}
/** Reports chosen history of direct/app share targets. */
@@ -72,6 +93,9 @@ class ShareTargetPredictor extends AppTargetPredictor {
if (mIntentFilter != null) {
getDataManager().reportShareTargetEvent(event, mIntentFilter);
}
if (mRemoteAppPredictor != null) {
mRemoteAppPredictor.notifyAppTargetEvent(event);
}
}
/** Provides prediction on direct share targets */
@@ -129,6 +153,15 @@ class ShareTargetPredictor extends AppTargetPredictor {
callback.accept(appTargetList);
}
/** Recycles resources. */
@WorkerThread
@Override
void destroy() {
if (mRemoteAppPredictor != null) {
mRemoteAppPredictor.destroy();
}
}
private List<ShareTarget> getDirectShareTargets() {
List<ShareTarget> shareTargets = new ArrayList<>();
List<ShareShortcutInfo> shareShortcuts =

View File

@@ -47,12 +47,14 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.test.TestLooper;
import android.provider.DeviceConfig;
import android.testing.AndroidTestingRunner;
import android.testing.TestableContext;
import android.testing.TestableLooper;
import androidx.test.InstrumentationRegistry;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.server.LocalServices;
import org.junit.After;
@@ -126,6 +128,10 @@ public final class PeopleServiceTest {
.setPredictedTargetCount(APP_PREDICTION_TARGET_COUNT)
.setExtras(new Bundle())
.build();
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED,
Boolean.toString(false),
true /* makeDefault*/);
}
@After

View File

@@ -22,13 +22,17 @@ import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionManager;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetEvent;
import android.app.prediction.AppTargetId;
import android.content.ComponentName;
import android.content.Context;
@@ -38,9 +42,11 @@ import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager.ShareShortcutInfo;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.Range;
import com.android.internal.app.ChooserActivity;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.server.people.data.ConversationInfo;
import com.android.server.people.data.DataManager;
import com.android.server.people.data.EventHistory;
@@ -71,6 +77,14 @@ public final class ShareTargetPredictorTest {
private static final String PACKAGE_3 = "pkg3";
private static final String CLASS_1 = "cls1";
private static final String CLASS_2 = "cls2";
private static final AppTargetEvent APP_TARGET_EVENT =
new AppTargetEvent.Builder(
new AppTarget.Builder(
new AppTargetId("cls1#pkg1"), PACKAGE_1, UserHandle.of(USER_ID)).build(),
AppTargetEvent.ACTION_LAUNCH)
.setLaunchLocation(ChooserActivity.LAUNCH_LOCATION_DIRECT_SHARE)
.build();
private static final IntentFilter INTENT_FILTER = IntentFilter.create("SEND", "text/plain");
@Mock private Context mContext;
@Mock private DataManager mDataManager;
@@ -102,17 +116,33 @@ public final class ShareTargetPredictorTest {
when(mDataManager.getShareShortcuts(any(), anyInt())).thenReturn(mShareShortcuts);
when(mDataManager.getPackage(PACKAGE_1, USER_ID)).thenReturn(mPackageData1);
when(mDataManager.getPackage(PACKAGE_2, USER_ID)).thenReturn(mPackageData2);
when(mContext.createContextAsUser(any(), any())).thenReturn(mContext);
when(mContext.getSystemServiceName(AppPredictionManager.class)).thenReturn(
Context.APP_PREDICTION_SERVICE);
when(mContext.getSystemService(AppPredictionManager.class))
.thenReturn(new AppPredictionManager(mContext));
Bundle bundle = new Bundle();
bundle.putObject(ChooserActivity.APP_PREDICTION_INTENT_FILTER_KEY,
IntentFilter.create("SEND", "text/plain"));
bundle.putObject(ChooserActivity.APP_PREDICTION_INTENT_FILTER_KEY, INTENT_FILTER);
AppPredictionContext predictionContext = new AppPredictionContext.Builder(mContext)
.setUiSurface(UI_SURFACE_SHARE)
.setPredictedTargetCount(NUM_PREDICTED_TARGETS)
.setExtras(bundle)
.build();
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED,
Boolean.toString(true),
true /* makeDefault*/);
mPredictor = new ShareTargetPredictor(
predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID);
predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID, mContext);
}
@Test
public void testReportAppTargetEvent() {
mPredictor.reportAppTargetEvent(APP_TARGET_EVENT);
verify(mDataManager, times(1))
.reportShareTargetEvent(eq(APP_TARGET_EVENT), eq(INTENT_FILTER));
}
@Test
@@ -240,7 +270,7 @@ public final class ShareTargetPredictorTest {
.setExtras(new Bundle())
.build();
mPredictor = new ShareTargetPredictor(
predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID);
predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID, mContext);
mPredictor.predictTargets();
@@ -349,7 +379,7 @@ public final class ShareTargetPredictorTest {
.setExtras(new Bundle())
.build();
mPredictor = new ShareTargetPredictor(
predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID);
predictionContext, mUpdatePredictionsMethod, mDataManager, USER_ID, mContext);
AppTarget appTarget1 = new AppTarget.Builder(
new AppTargetId("cls1#pkg1"), PACKAGE_1, UserHandle.of(USER_ID))
.build();