Avoid binder call when binding Slice

The ContentProvider will make unecessary binder calls when
trying to bind the Slice. We can call directly into the
provider and grab the slice in these cases.

Bug: 112563822
Test: systrace
Change-Id: Ia761afccd7d28cf5e41b7c1420715fd9446ac8e8
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 6517a9d..9603562 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -27,6 +27,7 @@
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Trace;
 import android.provider.Settings;
 import android.text.Layout;
 import android.text.TextUtils;
@@ -148,6 +149,7 @@
     }
 
     private void showSlice() {
+        Trace.beginSection("KeyguardSliceView#showSlice");
         if (mPulsing || mSlice == null) {
             mTitle.setVisibility(GONE);
             mRow.setVisibility(GONE);
@@ -236,6 +238,7 @@
         if (mContentChangeListener != null) {
             mContentChangeListener.run();
         }
+        Trace.endSection();
     }
 
     public void setPulsing(boolean pulsing, boolean animate) {
@@ -383,8 +386,23 @@
     }
 
     public void refresh() {
-        Slice slice = SliceViewManager.getInstance(getContext()).bindSlice(mKeyguardSliceUri);
+        Slice slice;
+        Trace.beginSection("KeyguardSliceView#refresh");
+        // We can optimize performance and avoid binder calls when we know that we're bound
+        // to a Slice on the same process.
+        if (KeyguardSliceProvider.KEYGUARD_SLICE_URI.equals(mKeyguardSliceUri.toString())) {
+            KeyguardSliceProvider instance = KeyguardSliceProvider.getAttachedInstance();
+            if (instance != null) {
+                slice = instance.onBindSlice(mKeyguardSliceUri);
+            } else {
+                Log.w(TAG, "Keyguard slice not bound yet?");
+                slice = null;
+            }
+        } else {
+            slice = SliceViewManager.getInstance(getContext()).bindSlice(mKeyguardSliceUri);
+        }
         onChanged(slice);
+        Trace.endSection();
     }
 
     public static class Row extends LinearLayout {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index c96aa73..82b79ac 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -30,6 +30,7 @@
 import android.icu.text.DisplayContext;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.Trace;
 import android.provider.Settings;
 import android.service.notification.ZenModeConfig;
 import android.text.TextUtils;
@@ -72,6 +73,8 @@
     @VisibleForTesting
     static final int ALARM_VISIBILITY_HOURS = 12;
 
+    private static KeyguardSliceProvider sInstance;
+
     protected final Uri mSliceUri;
     protected final Uri mDateUri;
     protected final Uri mAlarmUri;
@@ -89,6 +92,7 @@
     protected AlarmManager mAlarmManager;
     protected ContentResolver mContentResolver;
     private AlarmManager.AlarmClockInfo mNextAlarmInfo;
+    private PendingIntent mPendingIntent;
 
     /**
      * Receiver responsible for time ticking and updating the date format.
@@ -117,6 +121,10 @@
         this(new Handler());
     }
 
+    public static KeyguardSliceProvider getAttachedInstance() {
+        return KeyguardSliceProvider.sInstance;
+    }
+
     @VisibleForTesting
     KeyguardSliceProvider(Handler handler) {
         mHandler = handler;
@@ -128,23 +136,24 @@
 
     @Override
     public Slice onBindSlice(Uri sliceUri) {
+        Trace.beginSection("KeyguardSliceProvider#onBindSlice");
         ListBuilder builder = new ListBuilder(getContext(), mSliceUri, ListBuilder.INFINITY);
         builder.addRow(new RowBuilder(mDateUri).setTitle(mLastText));
         addNextAlarm(builder);
         addZenMode(builder);
         addPrimaryAction(builder);
-        return builder.build();
+        Slice slice = builder.build();
+        Trace.endSection();
+        return slice;
     }
 
     protected void addPrimaryAction(ListBuilder builder) {
         // Add simple action because API requires it; Keyguard handles presenting
         // its own slices so this action + icon are actually never used.
-        PendingIntent pi = PendingIntent.getActivity(getContext(), 0, new Intent(), 0);
         IconCompat icon = IconCompat.createWithResource(getContext(),
                 R.drawable.ic_access_alarms_big);
-        SliceAction action = SliceAction.createDeeplink(pi, icon,
+        SliceAction action = SliceAction.createDeeplink(mPendingIntent, icon,
                 ListBuilder.ICON_IMAGE, mLastText);
-
         RowBuilder primaryActionRow = new RowBuilder(Uri.parse(KEYGUARD_ACTION_URI))
                 .setPrimaryAction(action);
         builder.addRow(primaryActionRow);
@@ -154,7 +163,6 @@
         if (TextUtils.isEmpty(mNextAlarm)) {
             return;
         }
-
         IconCompat alarmIcon = IconCompat.createWithResource(getContext(),
                 R.drawable.ic_access_alarms_big);
         RowBuilder alarmRowBuilder = new RowBuilder(mAlarmUri)
@@ -198,6 +206,8 @@
         mZenModeController = new ZenModeControllerImpl(getContext(), mHandler);
         mZenModeController.addCallback(this);
         mDatePattern = getContext().getString(R.string.system_ui_aod_date_pattern);
+        mPendingIntent = PendingIntent.getActivity(getContext(), 0, new Intent(), 0);
+        KeyguardSliceProvider.sInstance = this;
         registerClockUpdate();
         updateClock();
         return true;