1 /* 2 * Copyright (C) 2018 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 17 package android.app; 18 19 import android.app.ActivityManager; 20 import android.app.ActivityTaskManager; 21 import android.app.ApplicationErrorReport; 22 import android.app.ContentProviderHolder; 23 import android.app.GrantedUriPermission; 24 import android.app.IApplicationThread; 25 import android.app.IActivityClientController; 26 import android.app.IActivityController; 27 import android.app.IAssistDataReceiver; 28 import android.app.IInstrumentationWatcher; 29 import android.app.IProcessObserver; 30 import android.app.IScreenCaptureObserver; 31 import android.app.IServiceConnection; 32 import android.app.IStopUserCallback; 33 import android.app.ITaskStackListener; 34 import android.app.IUiAutomationConnection; 35 import android.app.IUidObserver; 36 import android.app.IUserSwitchObserver; 37 import android.app.Notification; 38 import android.app.PendingIntent; 39 import android.app.PictureInPictureUiState; 40 import android.app.ProfilerInfo; 41 import android.app.WaitResult; 42 import android.app.assist.AssistContent; 43 import android.app.assist.AssistStructure; 44 import android.content.ComponentName; 45 import android.content.IIntentReceiver; 46 import android.content.IIntentSender; 47 import android.content.Intent; 48 import android.content.IntentFilter; 49 import android.content.IntentSender; 50 import android.content.pm.ApplicationInfo; 51 import android.content.pm.ConfigurationInfo; 52 import android.content.pm.IPackageDataObserver; 53 import android.content.pm.ParceledListSlice; 54 import android.content.pm.ProviderInfo; 55 import android.content.pm.UserInfo; 56 import android.content.res.Configuration; 57 import android.graphics.Bitmap; 58 import android.graphics.GraphicBuffer; 59 import android.graphics.Point; 60 import android.graphics.Rect; 61 import android.net.Uri; 62 import android.os.Bundle; 63 import android.os.Debug; 64 import android.os.IBinder; 65 import android.os.IProgressListener; 66 import android.os.ParcelFileDescriptor; 67 import android.os.RemoteCallback; 68 import android.os.StrictMode; 69 import android.os.WorkSource; 70 import android.service.voice.IVoiceInteractionSession; 71 import android.view.IRecentsAnimationRunner; 72 import android.view.IRemoteAnimationRunner; 73 import android.view.RemoteAnimationDefinition; 74 import android.view.RemoteAnimationAdapter; 75 import android.window.IWindowOrganizerController; 76 import android.window.BackAnimationAdapter; 77 import android.window.BackNavigationInfo; 78 import android.window.SplashScreenView; 79 import com.android.internal.app.IVoiceInteractor; 80 import com.android.internal.os.IResultReceiver; 81 82 import java.util.List; 83 84 /** 85 * System private API for talking with the activity task manager that handles how activities are 86 * managed on screen. 87 * 88 * {@hide} 89 */ 90 // TODO(b/174040395): Make this interface private to ActivityTaskManager.java and have external 91 // caller go through that call instead. This would help us better separate and control the API 92 // surface exposed. 93 // TODO(b/174041603): Create a builder interface for things like startActivityXXX(...) to reduce 94 // interface duplication. 95 interface IActivityTaskManager { startActivity(in IApplicationThread caller, in String callingPackage, in String callingFeatureId, in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options)96 int startActivity(in IApplicationThread caller, in String callingPackage, 97 in String callingFeatureId, in Intent intent, in String resolvedType, 98 in IBinder resultTo, in String resultWho, int requestCode, 99 int flags, in ProfilerInfo profilerInfo, in Bundle options); startActivities(in IApplicationThread caller, in String callingPackage, in String callingFeatureId, in Intent[] intents, in String[] resolvedTypes, in IBinder resultTo, in Bundle options, int userId)100 int startActivities(in IApplicationThread caller, in String callingPackage, 101 in String callingFeatureId, in Intent[] intents, in String[] resolvedTypes, 102 in IBinder resultTo, in Bundle options, int userId); startActivityAsUser(in IApplicationThread caller, in String callingPackage, in String callingFeatureId, in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options, int userId)103 int startActivityAsUser(in IApplicationThread caller, in String callingPackage, 104 in String callingFeatureId, in Intent intent, in String resolvedType, 105 in IBinder resultTo, in String resultWho, int requestCode, int flags, 106 in ProfilerInfo profilerInfo, in Bundle options, int userId); startNextMatchingActivity(in IBinder callingActivity, in Intent intent, in Bundle options)107 boolean startNextMatchingActivity(in IBinder callingActivity, 108 in Intent intent, in Bundle options); startActivityIntentSender(in IApplicationThread caller, in IIntentSender target, in IBinder whitelistToken, in Intent fillInIntent, in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode, int flagsMask, int flagsValues, in Bundle options)109 int startActivityIntentSender(in IApplicationThread caller, 110 in IIntentSender target, in IBinder whitelistToken, in Intent fillInIntent, 111 in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode, 112 int flagsMask, int flagsValues, in Bundle options); startActivityAndWait(in IApplicationThread caller, in String callingPackage, in String callingFeatureId, in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options, int userId)113 WaitResult startActivityAndWait(in IApplicationThread caller, in String callingPackage, 114 in String callingFeatureId, in Intent intent, in String resolvedType, 115 in IBinder resultTo, in String resultWho, int requestCode, int flags, 116 in ProfilerInfo profilerInfo, in Bundle options, int userId); startActivityWithConfig(in IApplicationThread caller, in String callingPackage, in String callingFeatureId, in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode, int startFlags, in Configuration newConfig, in Bundle options, int userId)117 int startActivityWithConfig(in IApplicationThread caller, in String callingPackage, 118 in String callingFeatureId, in Intent intent, in String resolvedType, 119 in IBinder resultTo, in String resultWho, int requestCode, int startFlags, 120 in Configuration newConfig, in Bundle options, int userId); startVoiceActivity(in String callingPackage, in String callingFeatureId, int callingPid, int callingUid, in Intent intent, in String resolvedType, in IVoiceInteractionSession session, in IVoiceInteractor interactor, int flags, in ProfilerInfo profilerInfo, in Bundle options, int userId)121 int startVoiceActivity(in String callingPackage, in String callingFeatureId, int callingPid, 122 int callingUid, in Intent intent, in String resolvedType, 123 in IVoiceInteractionSession session, in IVoiceInteractor interactor, int flags, 124 in ProfilerInfo profilerInfo, in Bundle options, int userId); getVoiceInteractorPackageName(in IBinder callingVoiceInteractor)125 String getVoiceInteractorPackageName(in IBinder callingVoiceInteractor); startAssistantActivity(in String callingPackage, in String callingFeatureId, int callingPid, int callingUid, in Intent intent, in String resolvedType, in Bundle options, int userId)126 int startAssistantActivity(in String callingPackage, in String callingFeatureId, int callingPid, 127 int callingUid, in Intent intent, in String resolvedType, in Bundle options, int userId); 128 @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_ACTIVITY)") startActivityFromGameSession(IApplicationThread caller, in String callingPackage, in String callingFeatureId, int callingPid, int callingUid, in Intent intent, int taskId, int userId)129 int startActivityFromGameSession(IApplicationThread caller, in String callingPackage, 130 in String callingFeatureId, int callingPid, int callingUid, in Intent intent, 131 int taskId, int userId); startRecentsActivity(in Intent intent, in long eventTime, in IRecentsAnimationRunner recentsAnimationRunner)132 void startRecentsActivity(in Intent intent, in long eventTime, 133 in IRecentsAnimationRunner recentsAnimationRunner); startActivityFromRecents(int taskId, in Bundle options)134 int startActivityFromRecents(int taskId, in Bundle options); startActivityAsCaller(in IApplicationThread caller, in String callingPackage, in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options, boolean ignoreTargetSecurity, int userId)135 int startActivityAsCaller(in IApplicationThread caller, in String callingPackage, 136 in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho, 137 int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options, 138 boolean ignoreTargetSecurity, int userId); 139 isActivityStartAllowedOnDisplay(int displayId, in Intent intent, in String resolvedType, int userId)140 boolean isActivityStartAllowedOnDisplay(int displayId, in Intent intent, in String resolvedType, 141 int userId); 142 unhandledBack()143 void unhandledBack(); 144 145 /** Returns an interface to control the activity related operations. */ getActivityClientController()146 IActivityClientController getActivityClientController(); 147 getFrontActivityScreenCompatMode()148 int getFrontActivityScreenCompatMode(); setFrontActivityScreenCompatMode(int mode)149 void setFrontActivityScreenCompatMode(int mode); setFocusedTask(int taskId)150 void setFocusedTask(int taskId); removeTask(int taskId)151 boolean removeTask(int taskId); removeAllVisibleRecentTasks()152 void removeAllVisibleRecentTasks(); getTasks(int maxNum, boolean filterOnlyVisibleRecents, boolean keepIntentExtra, int displayId)153 List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, boolean filterOnlyVisibleRecents, 154 boolean keepIntentExtra, int displayId); moveTaskToFront(in IApplicationThread app, in String callingPackage, int task, int flags, in Bundle options)155 void moveTaskToFront(in IApplicationThread app, in String callingPackage, int task, 156 int flags, in Bundle options); getRecentTasks(int maxNum, int flags, int userId)157 ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, 158 int userId); isTopActivityImmersive()159 boolean isTopActivityImmersive(); getTaskDescription(int taskId)160 ActivityManager.TaskDescription getTaskDescription(int taskId); reportAssistContextExtras(in IBinder assistToken, in Bundle extras, in AssistStructure structure, in AssistContent content, in Uri referrer)161 void reportAssistContextExtras(in IBinder assistToken, in Bundle extras, 162 in AssistStructure structure, in AssistContent content, in Uri referrer); 163 setFocusedRootTask(int taskId)164 void setFocusedRootTask(int taskId); getFocusedRootTaskInfo()165 ActivityTaskManager.RootTaskInfo getFocusedRootTaskInfo(); getTaskBounds(int taskId)166 Rect getTaskBounds(int taskId); 167 168 /** Focuses the top task on a display if it isn't already focused. Used for Recents. */ focusTopTask(int displayId)169 void focusTopTask(int displayId); 170 cancelRecentsAnimation(boolean restoreHomeRootTaskPosition)171 void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition); 172 @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES)") updateLockTaskPackages(int userId, in String[] packages)173 void updateLockTaskPackages(int userId, in String[] packages); isInLockTaskMode()174 boolean isInLockTaskMode(); getLockTaskModeState()175 int getLockTaskModeState(); getAppTasks(in String callingPackage)176 List<IBinder> getAppTasks(in String callingPackage); startSystemLockTaskMode(int taskId)177 void startSystemLockTaskMode(int taskId); stopSystemLockTaskMode()178 void stopSystemLockTaskMode(); finishVoiceTask(in IVoiceInteractionSession session)179 void finishVoiceTask(in IVoiceInteractionSession session); addAppTask(in IBinder activityToken, in Intent intent, in ActivityManager.TaskDescription description, in Bitmap thumbnail)180 int addAppTask(in IBinder activityToken, in Intent intent, 181 in ActivityManager.TaskDescription description, in Bitmap thumbnail); getAppTaskThumbnailSize()182 Point getAppTaskThumbnailSize(); 183 releaseSomeActivities(in IApplicationThread app)184 oneway void releaseSomeActivities(in IApplicationThread app); getTaskDescriptionIcon(in String filename, int userId)185 Bitmap getTaskDescriptionIcon(in String filename, int userId); registerTaskStackListener(in ITaskStackListener listener)186 void registerTaskStackListener(in ITaskStackListener listener); unregisterTaskStackListener(in ITaskStackListener listener)187 void unregisterTaskStackListener(in ITaskStackListener listener); setTaskResizeable(int taskId, int resizeableMode)188 void setTaskResizeable(int taskId, int resizeableMode); 189 190 /** 191 * Resize the task with given bounds 192 * 193 * @param taskId The id of the task to set the bounds for. 194 * @param bounds The new bounds. 195 * @param resizeMode Resize mode defined as {@code ActivityTaskManager#RESIZE_MODE_*} constants. 196 */ resizeTask(int taskId, in Rect bounds, int resizeMode)197 void resizeTask(int taskId, in Rect bounds, int resizeMode); moveRootTaskToDisplay(int taskId, int displayId)198 void moveRootTaskToDisplay(int taskId, int displayId); 199 moveTaskToRootTask(int taskId, int rootTaskId, boolean toTop)200 void moveTaskToRootTask(int taskId, int rootTaskId, boolean toTop); 201 202 /** 203 * Removes root tasks in the input windowing modes from the system if they are of activity type 204 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED 205 */ removeRootTasksInWindowingModes(in int[] windowingModes)206 void removeRootTasksInWindowingModes(in int[] windowingModes); 207 /** Removes root tasks of the activity types from the system. */ removeRootTasksWithActivityTypes(in int[] activityTypes)208 void removeRootTasksWithActivityTypes(in int[] activityTypes); 209 getAllRootTaskInfos()210 List<ActivityTaskManager.RootTaskInfo> getAllRootTaskInfos(); getRootTaskInfo(int windowingMode, int activityType)211 ActivityTaskManager.RootTaskInfo getRootTaskInfo(int windowingMode, int activityType); getAllRootTaskInfosOnDisplay(int displayId)212 List<ActivityTaskManager.RootTaskInfo> getAllRootTaskInfosOnDisplay(int displayId); getRootTaskInfoOnDisplay(int windowingMode, int activityType, int displayId)213 ActivityTaskManager.RootTaskInfo getRootTaskInfoOnDisplay(int windowingMode, int activityType, int displayId); 214 215 /** 216 * Informs ActivityTaskManagerService that the keyguard is showing. 217 * 218 * @param showingKeyguard True if the keyguard is showing, false otherwise. 219 * @param showingAod True if AOD is showing, false otherwise. 220 */ setLockScreenShown(boolean showingKeyguard, boolean showingAod)221 void setLockScreenShown(boolean showingKeyguard, boolean showingAod); getAssistContextExtras(int requestType)222 Bundle getAssistContextExtras(int requestType); requestAssistContextExtras(int requestType, in IAssistDataReceiver receiver, in Bundle receiverExtras, in IBinder activityToken, boolean focused, boolean newSessionId)223 boolean requestAssistContextExtras(int requestType, in IAssistDataReceiver receiver, 224 in Bundle receiverExtras, in IBinder activityToken, 225 boolean focused, boolean newSessionId); requestAutofillData(in IAssistDataReceiver receiver, in Bundle receiverExtras, in IBinder activityToken, int flags)226 boolean requestAutofillData(in IAssistDataReceiver receiver, in Bundle receiverExtras, 227 in IBinder activityToken, int flags); isAssistDataAllowedOnCurrentActivity()228 boolean isAssistDataAllowedOnCurrentActivity(); requestAssistDataForTask(in IAssistDataReceiver receiver, int taskId, in String callingPackageName, String callingAttributionTag)229 boolean requestAssistDataForTask(in IAssistDataReceiver receiver, int taskId, 230 in String callingPackageName, String callingAttributionTag); 231 232 /** 233 * Notify the system that the keyguard is going away. 234 * 235 * @param flags See 236 * {@link android.view.WindowManagerPolicyConstants#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE} 237 * etc. 238 */ 239 @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD)") keyguardGoingAway(int flags)240 void keyguardGoingAway(int flags); 241 suppressResizeConfigChanges(boolean suppress)242 void suppressResizeConfigChanges(boolean suppress); 243 244 /** Returns an interface enabling the management of window organizers. */ getWindowOrganizerController()245 IWindowOrganizerController getWindowOrganizerController(); 246 supportsLocalVoiceInteraction()247 boolean supportsLocalVoiceInteraction(); 248 249 // Get device configuration getDeviceConfigurationInfo()250 ConfigurationInfo getDeviceConfigurationInfo(); 251 252 /** Cancels the window transitions for the given task. */ cancelTaskWindowTransition(int taskId)253 void cancelTaskWindowTransition(int taskId); 254 255 /** 256 * Fetches the snapshot for the task with the given id, taking a new snapshot if it is not in 257 * the task snapshot cache and it is requested. 258 * 259 * @param taskId the id of the task to retrieve the sAutoapshots for 260 * @param isLowResolution if set, if the snapshot needs to be loaded from disk, this will load 261 * a reduced resolution of it, which is much faster 262 * @param takeSnapshotIfNeeded if set, call {@link #takeTaskSnapshot} to trigger the snapshot 263 if no cache exists. 264 * @return a graphic buffer representing a screenshot of a task 265 */ getTaskSnapshot( int taskId, boolean isLowResolution, boolean takeSnapshotIfNeeded)266 android.window.TaskSnapshot getTaskSnapshot( 267 int taskId, boolean isLowResolution, boolean takeSnapshotIfNeeded); 268 269 /** 270 * Requests for a new snapshot to be taken for the task with the given id, storing it in the 271 * task snapshot cache only if requested. 272 * 273 * @param taskId the id of the task to take a snapshot of 274 * @param updateCache whether to store the new snapshot in the system's task snapshot cache 275 * @return a graphic buffer representing a screenshot of a task 276 */ takeTaskSnapshot(int taskId, boolean updateCache)277 android.window.TaskSnapshot takeTaskSnapshot(int taskId, boolean updateCache); 278 279 /** 280 * Return the user id of last resumed activity. 281 */ getLastResumedActivityUserId()282 int getLastResumedActivityUserId(); 283 284 /** 285 * Updates global configuration and applies changes to the entire system. 286 * @param values Update values for global configuration. If null is passed it will request the 287 * Window Manager to compute new config for the default display. 288 * @throws RemoteException 289 * @return Returns true if the configuration was updated. 290 */ updateConfiguration(in Configuration values)291 boolean updateConfiguration(in Configuration values); updateLockTaskFeatures(int userId, int flags)292 void updateLockTaskFeatures(int userId, int flags); 293 294 /** 295 * Registers a remote animation to be run for all activity starts from a certain package during 296 * a short predefined amount of time. 297 */ registerRemoteAnimationForNextActivityStart(in String packageName, in RemoteAnimationAdapter adapter, in IBinder launchCookie)298 void registerRemoteAnimationForNextActivityStart(in String packageName, 299 in RemoteAnimationAdapter adapter, in IBinder launchCookie); 300 301 /** 302 * Registers remote animations for a display. 303 */ registerRemoteAnimationsForDisplay(int displayId, in RemoteAnimationDefinition definition)304 void registerRemoteAnimationsForDisplay(int displayId, in RemoteAnimationDefinition definition); 305 306 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */ alwaysShowUnsupportedCompileSdkWarning(in ComponentName activity)307 void alwaysShowUnsupportedCompileSdkWarning(in ComponentName activity); 308 setVrThread(int tid)309 void setVrThread(int tid); setPersistentVrThread(int tid)310 void setPersistentVrThread(int tid); stopAppSwitches()311 void stopAppSwitches(); resumeAppSwitches()312 void resumeAppSwitches(); setActivityController(in IActivityController watcher, boolean imAMonkey)313 void setActivityController(in IActivityController watcher, boolean imAMonkey); setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake)314 void setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake); 315 getPackageScreenCompatMode(in String packageName)316 int getPackageScreenCompatMode(in String packageName); setPackageScreenCompatMode(in String packageName, int mode)317 void setPackageScreenCompatMode(in String packageName, int mode); getPackageAskScreenCompat(in String packageName)318 boolean getPackageAskScreenCompat(in String packageName); setPackageAskScreenCompat(in String packageName, boolean ask)319 void setPackageAskScreenCompat(in String packageName, boolean ask); 320 321 /** 322 * Clears launch params for given packages. 323 */ clearLaunchParamsForPackages(in List<String> packageNames)324 void clearLaunchParamsForPackages(in List<String> packageNames); 325 326 /** 327 * A splash screen view has copied. 328 */ onSplashScreenViewCopyFinished(int taskId, in SplashScreenView.SplashScreenViewParcelable material)329 void onSplashScreenViewCopyFinished(int taskId, 330 in SplashScreenView.SplashScreenViewParcelable material); 331 332 /** 333 * When the Picture-in-picture state has changed. 334 */ onPictureInPictureStateChanged(in PictureInPictureUiState pipState)335 void onPictureInPictureStateChanged(in PictureInPictureUiState pipState); 336 337 /** 338 * Re-attach navbar to the display during a recents transition. 339 * TODO(188595497): Remove this once navbar attachment is in shell. 340 */ detachNavigationBarFromApp(in IBinder transition)341 void detachNavigationBarFromApp(in IBinder transition); 342 343 /** 344 * Marks a process as a delegate for the currently playing remote transition animation. This 345 * must be called from a process that is already a remote transition player or delegate. Any 346 * marked delegates are cleaned-up automatically at the end of the transition. 347 * @param caller is the IApplicationThread representing the calling process. 348 */ setRunningRemoteTransitionDelegate(in IApplicationThread caller)349 void setRunningRemoteTransitionDelegate(in IApplicationThread caller); 350 351 /** 352 * Prepare the back navigation in the server. This setups the leashed for sysui to animate 353 * the back gesture and returns the data needed for the animation. 354 * @param navigationObserver a remote callback to nofify shell when the focused window is gone, 355 or an unexpected transition has happened on the navigation target. 356 * @param adaptor a remote animation to be run for the back navigation plays the animation. 357 * @return Returns the back navigation info. 358 */ startBackNavigation( in RemoteCallback navigationObserver, in BackAnimationAdapter adaptor)359 android.window.BackNavigationInfo startBackNavigation( 360 in RemoteCallback navigationObserver, in BackAnimationAdapter adaptor); 361 362 /** 363 * registers a callback to be invoked when the screen is captured. 364 * 365 * @param observer callback to be registered. 366 * @param activityToken The token for the activity to set the callback to. 367 * @hide 368 */ registerScreenCaptureObserver(IBinder activityToken, IScreenCaptureObserver observer)369 void registerScreenCaptureObserver(IBinder activityToken, IScreenCaptureObserver observer); 370 371 /** 372 * unregisters the screen capture callback which was registered with 373 * {@link #registerScreenCaptureObserver(ScreenCaptureObserver)}. 374 * 375 * @param observer callback to be unregistered. 376 * @param activityToken The token for the activity to unset the callback from. 377 * @hide 378 */ unregisterScreenCaptureObserver(IBinder activityToken, IScreenCaptureObserver observer)379 void unregisterScreenCaptureObserver(IBinder activityToken, IScreenCaptureObserver observer); 380 } 381