Merge "QS API: Fix mService and mTile being null once and for all" into nyc-dev
diff --git a/core/java/android/service/quicksettings/IQSTileService.aidl b/core/java/android/service/quicksettings/IQSTileService.aidl
index bfde870..b6c830c 100644
--- a/core/java/android/service/quicksettings/IQSTileService.aidl
+++ b/core/java/android/service/quicksettings/IQSTileService.aidl
@@ -15,15 +15,10 @@
  */
 package android.service.quicksettings;
 
-import android.service.quicksettings.Tile;
-import android.service.quicksettings.IQSService;
-
 /**
  * @hide
  */
 oneway interface IQSTileService {
-    void setQSService(in IQSService service);
-    void setQSTile(in Tile tile);
     void onTileAdded();
     void onTileRemoved();
     void onStartListening();
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 4e9a075..67793fd 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -118,6 +118,16 @@
     /**
      * @hide
      */
+    public static final String EXTRA_SERVICE = "service";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_TILE = "tile";
+
+    /**
+     * @hide
+     */
     public static final String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
 
     private final H mHandler = new H(Looper.getMainLooper());
@@ -305,18 +315,11 @@
 
     @Override
     public IBinder onBind(Intent intent) {
+        mTile = intent.getParcelableExtra(EXTRA_TILE);
+        mService = IQSService.Stub.asInterface(intent.getIBinderExtra(EXTRA_SERVICE));
+        mTile.setService(mService);
         return new IQSTileService.Stub() {
             @Override
-            public void setQSService(IQSService service) throws RemoteException {
-                mHandler.obtainMessage(H.MSG_SET_SERVICE, service).sendToTarget();
-            }
-
-            @Override
-            public void setQSTile(Tile tile) throws RemoteException {
-                mHandler.obtainMessage(H.MSG_SET_TILE, tile).sendToTarget();
-            }
-
-            @Override
             public void onTileRemoved() throws RemoteException {
                 mHandler.sendEmptyMessage(H.MSG_TILE_REMOVED);
             }
@@ -349,14 +352,12 @@
     }
 
     private class H extends Handler {
-        private static final int MSG_SET_TILE = 1;
-        private static final int MSG_START_LISTENING = 2;
-        private static final int MSG_STOP_LISTENING = 3;
-        private static final int MSG_TILE_ADDED = 4;
-        private static final int MSG_TILE_REMOVED = 5;
-        private static final int MSG_TILE_CLICKED = 6;
-        private static final int MSG_SET_SERVICE = 7;
-        private static final int MSG_UNLOCK_COMPLETE = 8;
+        private static final int MSG_START_LISTENING = 1;
+        private static final int MSG_STOP_LISTENING = 2;
+        private static final int MSG_TILE_ADDED = 3;
+        private static final int MSG_TILE_REMOVED = 4;
+        private static final int MSG_TILE_CLICKED = 5;
+        private static final int MSG_UNLOCK_COMPLETE = 6;
 
         public H(Looper looper) {
             super(looper);
@@ -365,18 +366,6 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MSG_SET_SERVICE:
-                    mService = (IQSService) msg.obj;
-                    if (mTile != null) {
-                        mTile.setService(mService);
-                    }
-                    break;
-                case MSG_SET_TILE:
-                    mTile = (Tile) msg.obj;
-                    if (mService != null && mTile != null) {
-                        mTile.setService(mService);
-                    }
-                    break;
                 case MSG_TILE_ADDED:
                     TileService.this.onTileAdded();
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 23a3ca1..46e7277 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -71,17 +71,12 @@
         super(host);
         mWindowManager = WindowManagerGlobal.getWindowManagerService();
         mComponent = ComponentName.unflattenFromString(action);
+        mTile = new Tile(mComponent);
+        setTileIcon();
         mServiceManager = host.getTileServices().getTileWrapper(this);
         mService = mServiceManager.getTileService();
         mServiceManager.setTileChangeListener(this);
-        mTile = new Tile(mComponent);
         mUser = ActivityManager.getCurrentUser();
-        setTileIcon();
-        try {
-            mService.setQSTile(mTile);
-        } catch (RemoteException e) {
-            // Called through wrapper, won't happen here.
-        }
     }
 
     private void setTileIcon() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
index 3830ac5..407453c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
@@ -35,16 +35,6 @@
         return mService.asBinder();
     }
 
-    public boolean setQSTile(Tile tile) {
-        try {
-            mService.setQSTile(tile);
-            return true;
-        } catch (Exception e) {
-            Log.d(TAG, "Caught exception from TileService", e);
-            return false;
-        }
-    }
-
     public boolean onTileAdded() {
         try {
             mService.onTileAdded();
@@ -95,16 +85,6 @@
         }
     }
 
-    public boolean setQSService(IQSService service) {
-        try {
-            mService.setQSService(service);
-            return true;
-        } catch (Exception e) {
-            Log.d(TAG, "Caught exception from TileService", e);
-            return false;
-        }
-    }
-
     public boolean onUnlockComplete() {
         try {
             mService.onUnlockComplete();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index 87d6307..dd46779 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -71,23 +71,24 @@
     private Set<Integer> mQueuedMessages = new ArraySet<>();
     private QSTileServiceWrapper mWrapper;
     private boolean mListening;
-    private Tile mTile;
     private IBinder mClickBinder;
 
     private int mBindTryCount;
     private boolean mBound;
     @VisibleForTesting
     boolean mReceiverRegistered;
-    private IQSService mService;
     private boolean mUnbindImmediate;
     private TileChangeListener mChangeListener;
     // Return value from bindServiceAsUser, determines whether safe to call unbind.
     private boolean mIsBound;
 
-    public TileLifecycleManager(Handler handler, Context context, Intent intent, UserHandle user) {
+    public TileLifecycleManager(Handler handler, Context context, IQSService service,
+            Tile tile, Intent intent, UserHandle user) {
         mContext = context;
         mHandler = handler;
         mIntent = intent;
+        mIntent.putExtra(TileService.EXTRA_SERVICE, service.asBinder());
+        mIntent.putExtra(TileService.EXTRA_TILE, tile);
         mUser = user;
         if (DEBUG) Log.d(TAG, "Creating " + mIntent + " " + mUser);
     }
@@ -164,14 +165,6 @@
             service.linkToDeath(this, 0);
         } catch (RemoteException e) {
         }
-        if (!wrapper.setQSService(mService)) {
-            handleDeath();
-            return;
-        }
-        if (!wrapper.setQSTile(mTile)) {
-            handleDeath();
-            return;
-        }
         mWrapper = wrapper;
         handlePendingMessages();
     }
@@ -255,15 +248,6 @@
         }
     }
 
-    @Override
-    public void setQSTile(Tile tile) {
-        if (DEBUG) Log.d(TAG, "setQSTile " + tile);
-        mTile = tile;
-        if (mWrapper != null && !mWrapper.setQSTile(tile)) {
-            handleDeath();
-        }
-    }
-
     private boolean checkComponentState() {
         PackageManager pm = mContext.getPackageManager();
         if (!isPackageAvailable(pm) || !isComponentAvailable(pm)) {
@@ -347,14 +331,6 @@
     }
 
     @Override
-    public void setQSService(IQSService service) {
-        mService = service;
-        if (mWrapper == null || !mWrapper.setQSService(service)) {
-            handleDeath();
-        }
-    }
-
-    @Override
     public void onTileAdded() {
         if (DEBUG) Log.d(TAG, "onTileAdded");
         if (mWrapper == null || !mWrapper.onTileAdded()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
index ce9bbf4..3d030f9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
@@ -27,6 +27,7 @@
 import android.os.Handler;
 import android.os.UserHandle;
 import android.service.quicksettings.IQSTileService;
+import android.service.quicksettings.Tile;
 import android.service.quicksettings.TileService;
 import android.support.annotation.VisibleForTesting;
 import android.util.Log;
@@ -68,9 +69,10 @@
     // This defaults to true to ensure tiles start out unavailable.
     private boolean mPendingBind = true;
 
-    TileServiceManager(TileServices tileServices, Handler handler, ComponentName component) {
+    TileServiceManager(TileServices tileServices, Handler handler, ComponentName component,
+            Tile tile) {
         this(tileServices, handler, new TileLifecycleManager(handler,
-                tileServices.getContext(), new Intent().setComponent(component),
+                tileServices.getContext(), tileServices, tile, new Intent().setComponent(component),
                 new UserHandle(ActivityManager.getCurrentUser())));
     }
 
@@ -80,7 +82,6 @@
         mServices = tileServices;
         mHandler = handler;
         mStateManager = tileLifecycleManager;
-        mStateManager.setQSService(tileServices);
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 2ab6b5f..f84c5d0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -78,7 +78,7 @@
 
     public TileServiceManager getTileWrapper(CustomTile tile) {
         ComponentName component = tile.getComponent();
-        TileServiceManager service = onCreateTileService(component);
+        TileServiceManager service = onCreateTileService(component, tile.getQsTile());
         synchronized (mServices) {
             mServices.put(tile, service);
             mTiles.put(component, tile);
@@ -86,8 +86,8 @@
         return service;
     }
 
-    protected TileServiceManager onCreateTileService(ComponentName component) {
-        return new TileServiceManager(this, mHandler, component);
+    protected TileServiceManager onCreateTileService(ComponentName component, Tile tile) {
+        return new TileServiceManager(this, mHandler, component, tile);
     }
 
     public void freeService(CustomTile tile, TileServiceManager service) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 68e5d0b..fa57775 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -29,6 +29,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
+import android.service.quicksettings.Tile;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
@@ -399,10 +400,11 @@
             String tileSpec = previousTiles.get(i);
             if (!tileSpec.startsWith(CustomTile.PREFIX)) continue;
             if (!newTiles.contains(tileSpec)) {
-                Intent intent = new Intent().setComponent(
-                        CustomTile.getComponentFromSpec(tileSpec));
+                ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
+                Intent intent = new Intent().setComponent(component);
                 TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
-                        mContext, intent, new UserHandle(ActivityManager.getCurrentUser()));
+                        mContext, mServices, new Tile(component), intent,
+                        new UserHandle(ActivityManager.getCurrentUser()));
                 lifecycleManager.onStopListening();
                 lifecycleManager.onTileRemoved();
                 lifecycleManager.flushMessagesAndUnbind();
@@ -412,10 +414,11 @@
             String tileSpec = newTiles.get(i);
             if (!tileSpec.startsWith(CustomTile.PREFIX)) continue;
             if (!previousTiles.contains(tileSpec)) {
-                Intent intent = new Intent().setComponent(
-                        CustomTile.getComponentFromSpec(tileSpec));
+                ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
+                Intent intent = new Intent().setComponent(component);
                 TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
-                        mContext, intent, new UserHandle(ActivityManager.getCurrentUser()));
+                        mContext, mServices, new Tile(component), intent,
+                        new UserHandle(ActivityManager.getCurrentUser()));
                 lifecycleManager.onTileAdded();
                 lifecycleManager.flushMessagesAndUnbind();
             }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
index a30f507..c93377a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
@@ -36,6 +36,8 @@
 import android.util.ArraySet;
 import android.util.Log;
 
+import org.mockito.Mockito;
+
 @SmallTest
 public class TileLifecycleManagerTests extends AndroidTestCase {
     public static final String TILE_UPDATE_BROADCAST = "com.android.systemui.tests.TILE_UPDATE";
@@ -54,8 +56,11 @@
         mThread = new HandlerThread("TestThread");
         mThread.start();
         mHandler = new Handler(mThread.getLooper());
+        ComponentName component = new ComponentName(mContext, FakeTileService.class);
         mStateManager = new TileLifecycleManager(mHandler, getContext(),
-                new Intent(mContext, FakeTileService.class), new UserHandle(UserHandle.myUserId()));
+                Mockito.mock(IQSService.class), new Tile(component),
+                new Intent().setComponent(component),
+                new UserHandle(UserHandle.myUserId()));
         mCallbacks.clear();
         getContext().registerReceiver(mReceiver, new IntentFilter(TILE_UPDATE_BROADCAST));
     }
@@ -251,16 +256,6 @@
         @Override
         public IBinder onBind(Intent intent) {
             return new IQSTileService.Stub() {
-
-                @Override
-                public void setQSService(IQSService service) {
-
-                }
-
-                @Override
-                public void setQSTile(Tile tile) throws RemoteException {
-                }
-
                 @Override
                 public void onTileAdded() throws RemoteException {
                     sendCallback("onTileAdded");
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java
index 94c98d6..de3864d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java
@@ -17,6 +17,7 @@
 
 import android.content.ComponentName;
 import android.os.Looper;
+import android.service.quicksettings.Tile;
 import android.test.suitebuilder.annotation.SmallTest;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.phone.QSTileHost;
@@ -109,7 +110,7 @@
         }
 
         @Override
-        protected TileServiceManager onCreateTileService(ComponentName component) {
+        protected TileServiceManager onCreateTileService(ComponentName component, Tile qsTile) {
             TileServiceManager manager = Mockito.mock(TileServiceManager.class);
             mManagers.add(manager);
             return manager;