1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.launcher3; 17 18 import static android.content.Intent.EXTRA_COMPONENT_NAME; 19 import static android.content.Intent.EXTRA_USER; 20 21 import android.annotation.TargetApi; 22 import android.content.ComponentName; 23 import android.content.Intent; 24 import android.graphics.RectF; 25 import android.os.Build; 26 import android.os.Bundle; 27 import android.os.Message; 28 import android.os.RemoteException; 29 import android.os.UserHandle; 30 import android.util.Log; 31 import android.view.SurfaceControl; 32 33 import androidx.annotation.Nullable; 34 35 /** 36 * Class to encapsulate the handshake protocol between Launcher and gestureNav. 37 */ 38 public class GestureNavContract { 39 40 private static final String TAG = "GestureNavContract"; 41 42 public static final String EXTRA_GESTURE_CONTRACT = "gesture_nav_contract_v1"; 43 public static final String EXTRA_ICON_POSITION = "gesture_nav_contract_icon_position"; 44 public static final String EXTRA_ICON_SURFACE = "gesture_nav_contract_surface_control"; 45 public static final String EXTRA_REMOTE_CALLBACK = "android.intent.extra.REMOTE_CALLBACK"; 46 47 public final ComponentName componentName; 48 public final UserHandle user; 49 50 private final Message mCallback; 51 GestureNavContract(ComponentName componentName, UserHandle user, Message callback)52 public GestureNavContract(ComponentName componentName, UserHandle user, Message callback) { 53 this.componentName = componentName; 54 this.user = user; 55 this.mCallback = callback; 56 } 57 58 /** 59 * Sends the position information to the receiver 60 */ 61 @TargetApi(Build.VERSION_CODES.R) sendEndPosition(RectF position, @Nullable SurfaceControl surfaceControl)62 public void sendEndPosition(RectF position, @Nullable SurfaceControl surfaceControl) { 63 Bundle result = new Bundle(); 64 result.putParcelable(EXTRA_ICON_POSITION, position); 65 result.putParcelable(EXTRA_ICON_SURFACE, surfaceControl); 66 67 Message callback = Message.obtain(); 68 callback.copyFrom(mCallback); 69 callback.setData(result); 70 71 try { 72 callback.replyTo.send(callback); 73 } catch (RemoteException e) { 74 Log.e(TAG, "Error sending icon position", e); 75 } 76 } 77 78 /** 79 * Clears and returns the GestureNavContract if it was present in the intent. 80 */ fromIntent(Intent intent)81 public static GestureNavContract fromIntent(Intent intent) { 82 if (!Utilities.ATLEAST_R) { 83 return null; 84 } 85 Bundle extras = intent.getBundleExtra(EXTRA_GESTURE_CONTRACT); 86 if (extras == null) { 87 return null; 88 } 89 intent.removeExtra(EXTRA_GESTURE_CONTRACT); 90 91 ComponentName componentName = extras.getParcelable(EXTRA_COMPONENT_NAME); 92 UserHandle userHandle = extras.getParcelable(EXTRA_USER); 93 Message callback = extras.getParcelable(EXTRA_REMOTE_CALLBACK); 94 95 if (componentName != null && userHandle != null && callback != null 96 && callback.replyTo != null) { 97 return new GestureNavContract(componentName, userHandle, callback); 98 } 99 return null; 100 } 101 } 102