DND: Add a hidden DND tile to quick settings.

Invisible by default, not activatable when the platform
volume controller is active.

However, when the platform volume controller is not active,
it can be enabled via a broadcast intent.

When enabled, the status bar icon also changes to a single
dnd icon.

Very little more than embedding the existing zen mode panel
into the detail pane of a new QS tile.

Change-Id: I1e0ff6fbb99b00f67b53bceda8cbf121f3ef6b52
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d95b17e..479ef30 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5073,7 +5073,7 @@
     <string name="zen_mode_until">Until <xliff:g id="formattedTime" example="10:00 PM">%1$s</xliff:g></string>
 
     <!-- Zen mode condition: no exit criteria. [CHAR LIMIT=NONE] -->
-    <string name="zen_mode_forever">Indefinitely</string>
+    <string name="zen_mode_forever">Until you turn this off</string>
 
     <!-- Content description for the Toolbar icon used to collapse an expanded action mode. [CHAR LIMIT=NONE] -->
     <string name="toolbar_collapse_description">Collapse</string>
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml
new file mode 100644
index 0000000..28d2e26
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml
@@ -0,0 +1,41 @@
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="64dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
+    android:alpha=".3"
+    android:width="64dp" >
+
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M13.8,11.1L17.0,11.1l0.0,2.0l-1.2,0.0l4.5,4.5c1.1,-1.6 1.7,-3.5 1.7,-5.5c0.0,-5.5 -4.5,-10.0 -10.0,-10.0c-2.0,0.0 -3.9,0.6 -5.5,1.7L13.8,11.1z" />
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M13.0,13.1L7.0,13.1l0.0,-2.0l4.0,0.0L4.9,5.0C3.1,6.8 2.0,9.3 2.0,12.1c0.0,5.5 4.5,10.0 10.0,10.0c2.8,0.0 5.3,-1.1 7.1,-2.9L13.0,13.1z" />
+
+    <group
+        android:pivotX="12.0"
+        android:pivotY="12.0"
+        android:rotation="45.0"
+        android:translateX="0.5"
+        android:translateY="0.5" >
+        <path
+            android:fillColor="#FFFFFFFF"
+            android:pathData="M-2.8,11.8l28.3,0.0l0.0,2.0l-28.3,0.0z" />
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
new file mode 100644
index 0000000..7617ec4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="64dp"
+        android:height="64dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd.xml b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
new file mode 100644
index 0000000..9361bc0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp">
+    <vector
+            android:width="17dp"
+            android:height="17dp"
+            android:viewportWidth="48.0"
+            android:viewportHeight="48.0">
+        <path
+            android:fillColor="#FFFFFFFF"
+            android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z"/>
+    </vector>
+</inset>
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index 27353ff..33c1899 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -40,6 +40,16 @@
             android:clipChildren="false" />
     </FrameLayout>
 
+    <View
+        android:id="@+id/zen_embedded_divider"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:visibility="gone"
+        android:layout_marginStart="@dimen/qs_panel_padding"
+        android:layout_marginEnd="@dimen/qs_panel_padding"
+        android:layout_marginBottom="@dimen/qs_panel_padding"
+        android:background="#4dffffff" />
+
     <RelativeLayout
         android:id="@+id/zen_subhead"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 8a73fca..2e9e9f7 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -118,7 +118,7 @@
 
     <!-- The default tiles to display in QuickSettings -->
     <string name="quick_settings_tiles_default" translatable="false">
-        wifi,bt,inversion,cell,airplane,rotation,flashlight,location,cast,hotspot
+        wifi,bt,inversion,dnd,cell,airplane,rotation,flashlight,location,cast,hotspot
     </string>
 
     <!-- The tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d8b6a82..1b1b525 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -430,6 +430,16 @@
     <string name="accessibility_quick_settings_airplane_changed_off">Airplane mode turned off.</string>
     <!-- Announcement made when the airplane mode changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_airplane_changed_on">Airplane mode turned on.</string>
+    <!-- Content description of the do not disturb tile in quick settings when on in priority (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_dnd_priority_on">Do not disturb on, priority only.</string>
+    <!-- Content description of the do not disturb tile in quick settings when on in none (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_dnd_none_on">Do not disturb on, no interruptions.</string>
+     <!-- Content description of the do not disturb tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_dnd_off">Do not disturb off.</string>
+    <!-- Announcement made when do not disturb changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_dnd_changed_off">Do not disturb turned off.</string>
+    <!-- Announcement made when do not disturb changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_dnd_changed_on">Do not disturb turned on.</string>
     <!-- Content description of the bluetooth tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_bluetooth_off">Bluetooth off.</string>
     <!-- Content description of the bluetooth tile in quick settings when on (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -554,6 +564,12 @@
 
     <!-- QuickSettings: Airplane mode [CHAR LIMIT=NONE] -->
     <string name="quick_settings_airplane_mode_label">Airplane mode</string>
+    <!-- QuickSettings: Do not disturb [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_dnd_label">Do not disturb</string>
+    <!-- QuickSettings: Do not disturb - Priority only [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_dnd_priority_label">Priority only</string>
+    <!-- QuickSettings: Do not disturb - No interruptions [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_dnd_none_label">No interruptions</string>
     <!-- QuickSettings: Bluetooth [CHAR LIMIT=NONE] -->
     <string name="quick_settings_bluetooth_label">Bluetooth</string>
     <!-- QuickSettings: Bluetooth (Multiple) [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 4dacacf..7f944f0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -253,12 +253,6 @@
             @Override
             public void onStateChanged(QSTile.State state) {
                 int visibility = state.visible ? VISIBLE : GONE;
-                if (state.visible && !mGridContentVisible) {
-
-                    // We don't want to show it if the content is hidden,
-                    // then we just set it to invisible, to ensure that it gets visible again
-                    visibility = INVISIBLE;
-                }
                 setTileVisibility(r.tileView, visibility);
                 r.tileView.onStateChanged(state);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
new file mode 100644
index 0000000..79600f5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnAttachStateChangeListener;
+import android.view.ViewGroup;
+
+import com.android.systemui.R;
+import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.volume.ZenModePanel;
+
+/** Quick settings tile: Do not disturb **/
+public class DndTile extends QSTile<QSTile.BooleanState> {
+    private static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
+
+    private static final String ACTION_SET_VISIBLE = "com.android.systemui.dndtile.SET_VISIBLE";
+    private static final String EXTRA_VISIBLE = "visible";
+    private static final String PREF_KEY_VISIBLE = "DndTileVisible";
+
+    private final ZenModeController mController;
+    private final DndDetailAdapter mDetailAdapter;
+
+    private boolean mListening;
+    private boolean mVisible;
+    private boolean mShowingDetail;
+
+    public DndTile(Host host) {
+        super(host);
+        mController = host.getZenModeController();
+        mDetailAdapter = new DndDetailAdapter();
+        mVisible = getSharedPrefs(mContext).getBoolean(PREF_KEY_VISIBLE, false);
+        mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_SET_VISIBLE));
+    }
+
+    public static void setVisible(Context context, boolean visible) {
+        context.sendBroadcast(new Intent(DndTile.ACTION_SET_VISIBLE)
+                .putExtra(DndTile.EXTRA_VISIBLE, visible));
+    }
+
+    public static boolean isVisible(Context context) {
+        return getSharedPrefs(context).getBoolean(PREF_KEY_VISIBLE, false);
+    }
+
+    @Override
+    public DetailAdapter getDetailAdapter() {
+        return mDetailAdapter;
+    }
+
+    @Override
+    protected BooleanState newTileState() {
+        return new BooleanState();
+    }
+
+    @Override
+    public void handleClick() {
+        if (mState.value) {
+            mController.setZen(Global.ZEN_MODE_OFF);
+        } else {
+            mController.setZen(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+            showDetail(true);
+        }
+    }
+
+    @Override
+    protected void handleUpdateState(BooleanState state, Object arg) {
+        final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
+        state.value = zen != Global.ZEN_MODE_OFF;
+        state.visible = mVisible;
+        switch (zen) {
+            case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
+                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
+                state.label = mContext.getString(R.string.quick_settings_dnd_priority_label);
+                state.contentDescription = mContext.getString(
+                        R.string.accessibility_quick_settings_dnd_priority_on);
+                break;
+            case Global.ZEN_MODE_NO_INTERRUPTIONS:
+                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
+                state.label = mContext.getString(R.string.quick_settings_dnd_none_label);
+                state.contentDescription = mContext.getString(
+                        R.string.accessibility_quick_settings_dnd_none_on);
+                break;
+            default:
+                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_off);
+                state.label = mContext.getString(R.string.quick_settings_dnd_label);
+                state.contentDescription =  mContext.getString(
+                        R.string.accessibility_quick_settings_dnd_off);
+                break;
+        }
+        if (mShowingDetail && !state.value) {
+            showDetail(false);
+        }
+    }
+
+    @Override
+    protected String composeChangeAnnouncement() {
+        if (mState.value) {
+            return mContext.getString(R.string.accessibility_quick_settings_dnd_changed_on);
+        } else {
+            return mContext.getString(R.string.accessibility_quick_settings_dnd_changed_off);
+        }
+    }
+
+    @Override
+    public void setListening(boolean listening) {
+        if (mListening == listening) return;
+        mListening = listening;
+        if (mListening) {
+            mController.addCallback(mZenCallback);
+        } else {
+            mController.removeCallback(mZenCallback);
+        }
+    }
+
+    private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
+        public void onZenChanged(int zen) {
+            refreshState(zen);
+        }
+    };
+
+    private static SharedPreferences getSharedPrefs(Context context) {
+        return context.getSharedPreferences(context.getPackageName(), 0);
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mVisible = intent.getBooleanExtra(EXTRA_VISIBLE, false);
+            getSharedPrefs(mContext).edit().putBoolean(PREF_KEY_VISIBLE, mVisible).commit();
+            refreshState();
+        }
+    };
+
+    private final class DndDetailAdapter implements DetailAdapter, OnAttachStateChangeListener {
+
+        @Override
+        public int getTitle() {
+            return R.string.quick_settings_dnd_label;
+        }
+
+        @Override
+        public Boolean getToggleState() {
+            return mState.value;
+        }
+
+        @Override
+        public Intent getSettingsIntent() {
+            return ZEN_SETTINGS;
+        }
+
+        @Override
+        public void setToggleState(boolean state) {
+            if (!state) {
+                mController.setZen(Global.ZEN_MODE_OFF);
+                showDetail(false);
+            }
+        }
+
+        @Override
+        public View createDetailView(Context context, View convertView, ViewGroup parent) {
+            final ZenModePanel zmp = convertView != null ? (ZenModePanel) convertView
+                    : (ZenModePanel) LayoutInflater.from(context).inflate(
+                            R.layout.zen_mode_panel, parent, false);
+            if (convertView == null) {
+                zmp.init(mController);
+                zmp.setEmbedded(true);
+                zmp.addOnAttachStateChangeListener(this);
+            }
+            return zmp;
+        }
+
+        @Override
+        public void onViewAttachedToWindow(View v) {
+            mShowingDetail = true;
+        }
+
+        @Override
+        public void onViewDetachedFromWindow(View v) {
+            mShowingDetail = false;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index e8a000c..5da8457 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -33,6 +33,7 @@
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.systemui.R;
+import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.CastController.CastDevice;
 import com.android.systemui.statusbar.policy.HotspotController;
@@ -198,7 +199,11 @@
         int volumeIconId = 0;
         String volumeDescription = null;
 
-        if (mZen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
+        if (DndTile.isVisible(mContext)) {
+            zenVisible = mZen != Global.ZEN_MODE_OFF;
+            zenIconId = R.drawable.stat_sys_dnd;
+            zenDescription = mContext.getString(R.string.quick_settings_dnd_label);
+        } else if (mZen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
             zenVisible = true;
             zenIconId = R.drawable.stat_sys_zen_none;
             zenDescription = mContext.getString(R.string.zen_no_interruptions);
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 45a1386..954eb10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -41,6 +41,7 @@
 import com.android.systemui.qs.tiles.LocationTile;
 import com.android.systemui.qs.tiles.RotationLockTile;
 import com.android.systemui.qs.tiles.WifiTile;
+import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.settings.CurrentUserTracker;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.CastController;
@@ -256,6 +257,7 @@
         else if (tileSpec.equals("inversion")) return new ColorInversionTile(this);
         else if (tileSpec.equals("cell")) return new CellularTile(this);
         else if (tileSpec.equals("airplane")) return new AirplaneModeTile(this);
+        else if (tileSpec.equals("dnd")) return new DndTile(this);
         else if (tileSpec.equals("rotation")) return new RotationLockTile(this);
         else if (tileSpec.equals("flashlight")) return new FlashlightTile(this);
         else if (tileSpec.equals("location")) return new LocationTile(this);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index 8048a48..5e3ec3f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -44,6 +44,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.statusbar.ServiceMonitor;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
@@ -114,6 +115,7 @@
             if (LOGD) Log.d(TAG, "Registering volume controller");
             mAudioManager.setVolumeController(mVolumeController);
             mMediaSessionManager.setRemoteVolumeController(mRemoteVolumeController);
+            DndTile.setVisible(mContext, false);
         } else {
             if (LOGD) Log.d(TAG, "Unregistering volume controller");
             mAudioManager.setVolumeController(null);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 5726fa7..6cecc8f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -90,9 +90,11 @@
     private String mTag = TAG + "/" + Integer.toHexString(System.identityHashCode(this));
 
     private SegmentedButtons mZenButtons;
+    private ViewGroup mZenButtonsContainer;
     private View mZenSubhead;
     private TextView mZenSubheadCollapsed;
     private TextView mZenSubheadExpanded;
+    private View mZenEmbeddedDivider;
     private View mMoreSettings;
     private LinearLayout mZenConditions;
 
@@ -114,6 +116,7 @@
     private Condition mSessionExitCondition;
     private Condition[] mConditions;
     private Condition mTimeCondition;
+    private boolean mEmbedded;
 
     public ZenModePanel(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -140,9 +143,25 @@
         pw.print("  mExpanded="); pw.println(mExpanded);
         pw.print("  mSessionZen="); pw.println(mSessionZen);
         pw.print("  mAttachedZen="); pw.println(mAttachedZen);
+        pw.print("  mEmbedded="); pw.println(mEmbedded);
         mTransitionHelper.dump(fd, pw, args);
     }
 
+    public void setEmbedded(boolean embedded) {
+        if (mEmbedded == embedded) return;
+        mEmbedded = embedded;
+        mZenButtonsContainer.setLayoutTransition(mEmbedded ? null : newLayoutTransition(null));
+        if (mEmbedded) {
+            mZenButtonsContainer.setBackground(null);
+        } else {
+            mZenButtonsContainer.setBackgroundResource(R.drawable.qs_background_secondary);
+        }
+        mZenButtons.getChildAt(2).setVisibility(mEmbedded ? GONE : VISIBLE);
+        mZenEmbeddedDivider.setVisibility(mEmbedded ? VISIBLE : GONE);
+        setExpanded(mEmbedded);
+        updateWidgets();
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -156,10 +175,11 @@
                 Global.ZEN_MODE_OFF);
         mZenButtons.setCallback(mZenButtonsCallback);
 
-        final ViewGroup zenButtonsContainer = (ViewGroup) findViewById(R.id.zen_buttons_container);
-        zenButtonsContainer.setLayoutTransition(newLayoutTransition(null));
+        mZenButtonsContainer = (ViewGroup) findViewById(R.id.zen_buttons_container);
+        mZenButtonsContainer.setLayoutTransition(newLayoutTransition(null));
 
         mZenSubhead = findViewById(R.id.zen_subhead);
+        mZenEmbeddedDivider = findViewById(R.id.zen_embedded_divider);
 
         mZenSubheadCollapsed = (TextView) findViewById(R.id.zen_subhead_collapsed);
         mZenSubheadCollapsed.setOnClickListener(new View.OnClickListener() {
@@ -222,7 +242,9 @@
         mAttachedZen = -1;
         mSessionZen = -1;
         setSessionExitCondition(null);
-        setExpanded(false);
+        if (!mEmbedded) {
+            setExpanded(false);
+        }
         setRequestingConditions(false);
         mTransitionHelper.clear();
     }
@@ -361,7 +383,7 @@
 
     private void handleUpdateZen(int zen) {
         if (mSessionZen != -1 && mSessionZen != zen) {
-            setExpanded(zen != Global.ZEN_MODE_OFF);
+            setExpanded(mEmbedded || zen != Global.ZEN_MODE_OFF);
             mSessionZen = zen;
         }
         mZenButtons.setSelectedValue(zen);
@@ -403,7 +425,7 @@
         final boolean expanded = !mHidden && mExpanded;
 
         mZenButtons.setVisibility(mHidden ? GONE : VISIBLE);
-        mZenSubhead.setVisibility(!mHidden && !zenOff ? VISIBLE : GONE);
+        mZenSubhead.setVisibility(!mHidden && !zenOff && !mEmbedded ? VISIBLE : GONE);
         mZenSubheadExpanded.setVisibility(expanded ? VISIBLE : GONE);
         mZenSubheadCollapsed.setVisibility(!expanded ? VISIBLE : GONE);
         mMoreSettings.setVisibility(zenImportant && expanded ? VISIBLE : GONE);