Loading core/java/com/android/internal/statusbar/IStatusBarService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.internal.statusbar; import android.app.Notification; import android.net.Uri; import android.content.ComponentName; import android.graphics.Rect; import android.os.Bundle; Loading Loading @@ -77,6 +78,7 @@ interface IStatusBarService void onNotificationSettingsViewed(String key); void setSystemUiVisibility(int displayId, int vis, int mask, String cause); void onNotificationBubbleChanged(String key, boolean isBubble); void grantInlineReplyUriPermission(String key, in Uri uri); void onGlobalActionsShown(); void onGlobalActionsHidden(); Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +80 −8 Original line number Diff line number Diff line Loading @@ -23,12 +23,16 @@ import android.app.ActivityManager; import android.app.Notification; import android.app.PendingIntent; import android.app.RemoteInput; import android.content.ClipDescription; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ShortcutManager; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.text.Editable; Loading @@ -53,8 +57,13 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import androidx.core.view.inputmethod.EditorInfoCompat; import androidx.core.view.inputmethod.InputConnectionCompat; import androidx.core.view.inputmethod.InputContentInfoCompat; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; Loading @@ -65,6 +74,7 @@ import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewW import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.LightBarController; import java.util.HashMap; import java.util.function.Consumer; /** Loading @@ -88,6 +98,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private RemoteInputController mController; private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; private IStatusBarService mStatusBarManagerService; private NotificationEntry mEntry; private boolean mRemoved; Loading @@ -103,6 +115,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene public RemoteInputView(Context context, AttributeSet attrs) { super(context, attrs); mRemoteInputQuickSettingsDisabler = Dependency.get(RemoteInputQuickSettingsDisabler.class); mStatusBarManagerService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); } @Override Loading @@ -128,7 +142,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene if (isSoftImeEvent || isKeyboardEnterKey) { if (mEditText.length() > 0) { sendRemoteInput(); sendRemoteInput(prepareRemoteInputFromText()); } // Consume action to prevent IME from closing. return true; Loading @@ -141,7 +155,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEditText.mRemoteInputView = this; } private void sendRemoteInput() { protected Intent prepareRemoteInputFromText() { Bundle results = new Bundle(); results.putString(mRemoteInput.getResultKey(), mEditText.getText().toString()); Intent fillInIntent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); Loading @@ -153,6 +167,25 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_CHOICE); } return fillInIntent; } protected Intent prepareRemoteInputFromData(String contentType, Uri data) { HashMap<String, Uri> results = new HashMap<>(); results.put(contentType, data); try { mStatusBarManagerService.grantInlineReplyUriPermission( mEntry.notification.getKey(), data); } catch (Exception e) { Log.e(TAG, "Failed to grant URI permissions:" + e.getMessage(), e); } Intent fillInIntent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); RemoteInput.addDataResultToIntent(mRemoteInput, fillInIntent, results); return fillInIntent; } private void sendRemoteInput(Intent intent) { mEditText.setEnabled(false); mSendButton.setVisibility(INVISIBLE); mProgressBar.setVisibility(VISIBLE); Loading @@ -176,7 +209,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_SEND, mEntry.notification.getPackageName()); try { mPendingIntent.send(mContext, 0, fillInIntent); mPendingIntent.send(mContext, 0, intent); } catch (PendingIntent.CanceledException e) { Log.i(TAG, "Unable to send remote input result", e); MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_FAIL, Loading @@ -195,7 +228,9 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene LayoutInflater.from(context).inflate(R.layout.remote_input, root, false); v.mController = controller; v.mEntry = entry; v.mEditText.setTextOperationUser(computeTextOperationUser(entry.notification.getUser())); UserHandle user = computeTextOperationUser(entry.notification.getUser()); v.mEditText.mUser = user; v.mEditText.setTextOperationUser(user); v.setTag(VIEW_TAG); return v; Loading @@ -204,7 +239,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Override public void onClick(View v) { if (v == mSendButton) { sendRemoteInput(); sendRemoteInput(prepareRemoteInputFromText()); } } Loading Loading @@ -518,6 +553,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private RemoteInputView mRemoteInputView; boolean mShowImeOnInputConnection; private LightBarController mLightBarController; UserHandle mUser; public RemoteEditText(Context context, AttributeSet attrs) { super(context, attrs); Loading Loading @@ -617,11 +653,47 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { String[] allowedDataTypes = mRemoteInputView.mRemoteInput.getAllowedDataTypes() .toArray(new String[0]); EditorInfoCompat.setContentMimeTypes(outAttrs, allowedDataTypes); final InputConnection inputConnection = super.onCreateInputConnection(outAttrs); if (mShowImeOnInputConnection && inputConnection != null) { final InputConnectionCompat.OnCommitContentListener callback = new InputConnectionCompat.OnCommitContentListener() { @Override public boolean onCommitContent( InputContentInfoCompat inputContentInfoCompat, int i, Bundle bundle) { Uri contentUri = inputContentInfoCompat.getContentUri(); ClipDescription description = inputContentInfoCompat.getDescription(); String mimeType = null; if (description != null && description.getMimeTypeCount() > 0) { mimeType = description.getMimeType(0); } if (mimeType != null) { Intent dataIntent = mRemoteInputView.prepareRemoteInputFromData( mimeType, contentUri); mRemoteInputView.sendRemoteInput(dataIntent); } return true; } }; InputConnection ic = InputConnectionCompat.createWrapper( inputConnection, outAttrs, callback); Context userContext = null; try { userContext = mContext.createPackageContextAsUser( mContext.getPackageName(), 0, mUser); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Unable to create user context:" + e.getMessage(), e); } if (mShowImeOnInputConnection && ic != null) { Context targetContext = userContext != null ? userContext : getContext(); final InputMethodManager imm = getContext().getSystemService(InputMethodManager.class); targetContext.getSystemService(InputMethodManager.class); if (imm != null) { // onCreateInputConnection is called by InputMethodManager in the middle of // setting up the connection to the IME; wait with requesting the IME until that Loading @@ -636,7 +708,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } } return inputConnection; return ic; } @Override Loading services/core/java/com/android/server/notification/NotificationDelegate.java +7 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.notification; import android.app.Notification; import android.net.Uri; import android.service.notification.NotificationStats; import com.android.internal.statusbar.NotificationVisibility; Loading Loading @@ -48,6 +49,12 @@ public interface NotificationDelegate { void onNotificationSettingsViewed(String key); void onNotificationBubbleChanged(String key, boolean isBubble); /** * Grant permission to read the specified URI to the package associated with the * NotificationRecord associated with the given key. */ void grantInlineReplyUriPermission(String key, Uri uri, int callingUid); /** * Notifies that smart replies and actions have been added to the UI. */ Loading services/core/java/com/android/server/notification/NotificationManagerService.java +50 −1 Original line number Diff line number Diff line Loading @@ -1154,6 +1154,56 @@ public class NotificationManagerService extends SystemService { } } } @Override /** * Grant permission to read the specified URI to the package specified in the * NotificationRecord associated with the given key. The callingUid represents the UID of * SystemUI from which this method is being called. * * For this to work, SystemUI must have permission to read the URI when running under the * user associated with the NotificationRecord, and this grant will fail when trying * to grant URI permissions across users. */ public void grantInlineReplyUriPermission(String key, Uri uri, int callingUid) { synchronized (mNotificationLock) { NotificationRecord r = mNotificationsByKey.get(key); if (r != null) { IBinder owner = r.permissionOwner; if (owner == null) { r.permissionOwner = mUgmInternal.newUriPermissionOwner("NOTIF:" + key); owner = r.permissionOwner; } int uid = callingUid; int userId = r.sbn.getUserId(); if (userId == UserHandle.USER_ALL) { userId = USER_SYSTEM; } if (UserHandle.getUserId(uid) != userId) { try { final String[] pkgs = mPackageManager.getPackagesForUid(callingUid); if (pkgs == null) { Log.e(TAG, "Cannot grant uri permission to unknown UID: " + callingUid); } final String pkg = pkgs[0]; // Get the SystemUI package // Find the UID for SystemUI for the correct user uid = mPackageManager.getPackageUid(pkg, 0, userId); } catch (RemoteException re) { Log.e(TAG, "Cannot talk to package manager", re); } } grantUriPermission(owner, uri, uid, r.sbn.getPackageName(), userId); } else { Log.w(TAG, "No record found for notification key:" + key); // TODO: figure out cancel story. I think it's: sysui needs to tell us // whenever noitifications held by a lifetimextender go away // IBinder owner = mUgmInternal.newUriPermissionOwner("InlineReply:" + key); // pass in userId and package as well as key (key for logging purposes) } } } }; @VisibleForTesting Loading Loading @@ -7012,7 +7062,6 @@ public class NotificationManagerService extends SystemService { private void grantUriPermission(IBinder owner, Uri uri, int sourceUid, String targetPkg, int targetUserId) { if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return; final long ident = Binder.clearCallingIdentity(); try { mUgm.grantUriPermissionFromOwner(owner, sourceUid, targetPkg, Loading services/core/java/com/android/server/statusbar/StatusBarManagerService.java +13 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.graphics.Rect; import android.hardware.biometrics.IBiometricServiceReceiverInternal; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.Handler; Loading Loading @@ -1333,6 +1334,18 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } } @Override public void grantInlineReplyUriPermission(String key, Uri uri) { enforceStatusBarService(); int callingUid = Binder.getCallingUid(); long identity = Binder.clearCallingIdentity(); try { mNotificationDelegate.grantInlineReplyUriPermission(key, uri, callingUid); } finally { Binder.restoreCallingIdentity(identity); } } @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { Loading Loading
core/java/com/android/internal/statusbar/IStatusBarService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.internal.statusbar; import android.app.Notification; import android.net.Uri; import android.content.ComponentName; import android.graphics.Rect; import android.os.Bundle; Loading Loading @@ -77,6 +78,7 @@ interface IStatusBarService void onNotificationSettingsViewed(String key); void setSystemUiVisibility(int displayId, int vis, int mask, String cause); void onNotificationBubbleChanged(String key, boolean isBubble); void grantInlineReplyUriPermission(String key, in Uri uri); void onGlobalActionsShown(); void onGlobalActionsHidden(); Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +80 −8 Original line number Diff line number Diff line Loading @@ -23,12 +23,16 @@ import android.app.ActivityManager; import android.app.Notification; import android.app.PendingIntent; import android.app.RemoteInput; import android.content.ClipDescription; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ShortcutManager; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.text.Editable; Loading @@ -53,8 +57,13 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import androidx.core.view.inputmethod.EditorInfoCompat; import androidx.core.view.inputmethod.InputConnectionCompat; import androidx.core.view.inputmethod.InputContentInfoCompat; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; Loading @@ -65,6 +74,7 @@ import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewW import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.LightBarController; import java.util.HashMap; import java.util.function.Consumer; /** Loading @@ -88,6 +98,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private RemoteInputController mController; private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; private IStatusBarService mStatusBarManagerService; private NotificationEntry mEntry; private boolean mRemoved; Loading @@ -103,6 +115,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene public RemoteInputView(Context context, AttributeSet attrs) { super(context, attrs); mRemoteInputQuickSettingsDisabler = Dependency.get(RemoteInputQuickSettingsDisabler.class); mStatusBarManagerService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); } @Override Loading @@ -128,7 +142,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene if (isSoftImeEvent || isKeyboardEnterKey) { if (mEditText.length() > 0) { sendRemoteInput(); sendRemoteInput(prepareRemoteInputFromText()); } // Consume action to prevent IME from closing. return true; Loading @@ -141,7 +155,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEditText.mRemoteInputView = this; } private void sendRemoteInput() { protected Intent prepareRemoteInputFromText() { Bundle results = new Bundle(); results.putString(mRemoteInput.getResultKey(), mEditText.getText().toString()); Intent fillInIntent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); Loading @@ -153,6 +167,25 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_CHOICE); } return fillInIntent; } protected Intent prepareRemoteInputFromData(String contentType, Uri data) { HashMap<String, Uri> results = new HashMap<>(); results.put(contentType, data); try { mStatusBarManagerService.grantInlineReplyUriPermission( mEntry.notification.getKey(), data); } catch (Exception e) { Log.e(TAG, "Failed to grant URI permissions:" + e.getMessage(), e); } Intent fillInIntent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); RemoteInput.addDataResultToIntent(mRemoteInput, fillInIntent, results); return fillInIntent; } private void sendRemoteInput(Intent intent) { mEditText.setEnabled(false); mSendButton.setVisibility(INVISIBLE); mProgressBar.setVisibility(VISIBLE); Loading @@ -176,7 +209,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_SEND, mEntry.notification.getPackageName()); try { mPendingIntent.send(mContext, 0, fillInIntent); mPendingIntent.send(mContext, 0, intent); } catch (PendingIntent.CanceledException e) { Log.i(TAG, "Unable to send remote input result", e); MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_FAIL, Loading @@ -195,7 +228,9 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene LayoutInflater.from(context).inflate(R.layout.remote_input, root, false); v.mController = controller; v.mEntry = entry; v.mEditText.setTextOperationUser(computeTextOperationUser(entry.notification.getUser())); UserHandle user = computeTextOperationUser(entry.notification.getUser()); v.mEditText.mUser = user; v.mEditText.setTextOperationUser(user); v.setTag(VIEW_TAG); return v; Loading @@ -204,7 +239,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Override public void onClick(View v) { if (v == mSendButton) { sendRemoteInput(); sendRemoteInput(prepareRemoteInputFromText()); } } Loading Loading @@ -518,6 +553,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private RemoteInputView mRemoteInputView; boolean mShowImeOnInputConnection; private LightBarController mLightBarController; UserHandle mUser; public RemoteEditText(Context context, AttributeSet attrs) { super(context, attrs); Loading Loading @@ -617,11 +653,47 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { String[] allowedDataTypes = mRemoteInputView.mRemoteInput.getAllowedDataTypes() .toArray(new String[0]); EditorInfoCompat.setContentMimeTypes(outAttrs, allowedDataTypes); final InputConnection inputConnection = super.onCreateInputConnection(outAttrs); if (mShowImeOnInputConnection && inputConnection != null) { final InputConnectionCompat.OnCommitContentListener callback = new InputConnectionCompat.OnCommitContentListener() { @Override public boolean onCommitContent( InputContentInfoCompat inputContentInfoCompat, int i, Bundle bundle) { Uri contentUri = inputContentInfoCompat.getContentUri(); ClipDescription description = inputContentInfoCompat.getDescription(); String mimeType = null; if (description != null && description.getMimeTypeCount() > 0) { mimeType = description.getMimeType(0); } if (mimeType != null) { Intent dataIntent = mRemoteInputView.prepareRemoteInputFromData( mimeType, contentUri); mRemoteInputView.sendRemoteInput(dataIntent); } return true; } }; InputConnection ic = InputConnectionCompat.createWrapper( inputConnection, outAttrs, callback); Context userContext = null; try { userContext = mContext.createPackageContextAsUser( mContext.getPackageName(), 0, mUser); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Unable to create user context:" + e.getMessage(), e); } if (mShowImeOnInputConnection && ic != null) { Context targetContext = userContext != null ? userContext : getContext(); final InputMethodManager imm = getContext().getSystemService(InputMethodManager.class); targetContext.getSystemService(InputMethodManager.class); if (imm != null) { // onCreateInputConnection is called by InputMethodManager in the middle of // setting up the connection to the IME; wait with requesting the IME until that Loading @@ -636,7 +708,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } } return inputConnection; return ic; } @Override Loading
services/core/java/com/android/server/notification/NotificationDelegate.java +7 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.notification; import android.app.Notification; import android.net.Uri; import android.service.notification.NotificationStats; import com.android.internal.statusbar.NotificationVisibility; Loading Loading @@ -48,6 +49,12 @@ public interface NotificationDelegate { void onNotificationSettingsViewed(String key); void onNotificationBubbleChanged(String key, boolean isBubble); /** * Grant permission to read the specified URI to the package associated with the * NotificationRecord associated with the given key. */ void grantInlineReplyUriPermission(String key, Uri uri, int callingUid); /** * Notifies that smart replies and actions have been added to the UI. */ Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +50 −1 Original line number Diff line number Diff line Loading @@ -1154,6 +1154,56 @@ public class NotificationManagerService extends SystemService { } } } @Override /** * Grant permission to read the specified URI to the package specified in the * NotificationRecord associated with the given key. The callingUid represents the UID of * SystemUI from which this method is being called. * * For this to work, SystemUI must have permission to read the URI when running under the * user associated with the NotificationRecord, and this grant will fail when trying * to grant URI permissions across users. */ public void grantInlineReplyUriPermission(String key, Uri uri, int callingUid) { synchronized (mNotificationLock) { NotificationRecord r = mNotificationsByKey.get(key); if (r != null) { IBinder owner = r.permissionOwner; if (owner == null) { r.permissionOwner = mUgmInternal.newUriPermissionOwner("NOTIF:" + key); owner = r.permissionOwner; } int uid = callingUid; int userId = r.sbn.getUserId(); if (userId == UserHandle.USER_ALL) { userId = USER_SYSTEM; } if (UserHandle.getUserId(uid) != userId) { try { final String[] pkgs = mPackageManager.getPackagesForUid(callingUid); if (pkgs == null) { Log.e(TAG, "Cannot grant uri permission to unknown UID: " + callingUid); } final String pkg = pkgs[0]; // Get the SystemUI package // Find the UID for SystemUI for the correct user uid = mPackageManager.getPackageUid(pkg, 0, userId); } catch (RemoteException re) { Log.e(TAG, "Cannot talk to package manager", re); } } grantUriPermission(owner, uri, uid, r.sbn.getPackageName(), userId); } else { Log.w(TAG, "No record found for notification key:" + key); // TODO: figure out cancel story. I think it's: sysui needs to tell us // whenever noitifications held by a lifetimextender go away // IBinder owner = mUgmInternal.newUriPermissionOwner("InlineReply:" + key); // pass in userId and package as well as key (key for logging purposes) } } } }; @VisibleForTesting Loading Loading @@ -7012,7 +7062,6 @@ public class NotificationManagerService extends SystemService { private void grantUriPermission(IBinder owner, Uri uri, int sourceUid, String targetPkg, int targetUserId) { if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return; final long ident = Binder.clearCallingIdentity(); try { mUgm.grantUriPermissionFromOwner(owner, sourceUid, targetPkg, Loading
services/core/java/com/android/server/statusbar/StatusBarManagerService.java +13 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.graphics.Rect; import android.hardware.biometrics.IBiometricServiceReceiverInternal; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.Handler; Loading Loading @@ -1333,6 +1334,18 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } } @Override public void grantInlineReplyUriPermission(String key, Uri uri) { enforceStatusBarService(); int callingUid = Binder.getCallingUid(); long identity = Binder.clearCallingIdentity(); try { mNotificationDelegate.grantInlineReplyUriPermission(key, uri, callingUid); } finally { Binder.restoreCallingIdentity(identity); } } @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { Loading