Merge "Work on QS layouts"
diff --git a/core/java/android/print/PrintFileDocumentAdapter.java b/core/java/android/print/PrintFileDocumentAdapter.java
index 5d655bf..747400d 100644
--- a/core/java/android/print/PrintFileDocumentAdapter.java
+++ b/core/java/android/print/PrintFileDocumentAdapter.java
@@ -46,7 +46,7 @@
  */
 public class PrintFileDocumentAdapter extends PrintDocumentAdapter {
 
-    private static final String LOG_TAG = "PrintedFileDocumentAdapter";
+    private static final String LOG_TAG = "PrintedFileDocAdapter";
 
     private final Context mContext;
 
diff --git a/core/java/android/printservice/CustomPrinterIconCallback.java b/core/java/android/printservice/CustomPrinterIconCallback.java
index ea9ea8b..6b9d0d8 100644
--- a/core/java/android/printservice/CustomPrinterIconCallback.java
+++ b/core/java/android/printservice/CustomPrinterIconCallback.java
@@ -31,7 +31,7 @@
     /** The printer the call back is for */
     private final @NonNull PrinterId mPrinterId;
     private final @NonNull IPrintServiceClient mObserver;
-    private static final String LOG_TAG = "CustomPrinterIconCallback";
+    private static final String LOG_TAG = "CustomPrinterIconCB";
 
     /**
      * Create a callback class to be used once a icon is loaded
diff --git a/core/java/org/apache/http/conn/ssl/AbstractVerifier.java b/core/java/org/apache/http/conn/ssl/AbstractVerifier.java
index 66a5121..b9349b39 100644
--- a/core/java/org/apache/http/conn/ssl/AbstractVerifier.java
+++ b/core/java/org/apache/http/conn/ssl/AbstractVerifier.java
@@ -208,8 +208,8 @@
     }
 
     public static String[] getCNs(X509Certificate cert) {
-        DistinguishedNameParser dnParser =
-                new DistinguishedNameParser(cert.getSubjectX500Principal());
+        AndroidDistinguishedNameParser dnParser =
+                new AndroidDistinguishedNameParser(cert.getSubjectX500Principal());
         List<String> cnList = dnParser.getAllMostSpecificFirst("cn");
 
         if(!cnList.isEmpty()) {
diff --git a/core/java/org/apache/http/conn/ssl/DistinguishedNameParser.java b/core/java/org/apache/http/conn/ssl/AndroidDistinguishedNameParser.java
similarity index 99%
rename from core/java/org/apache/http/conn/ssl/DistinguishedNameParser.java
rename to core/java/org/apache/http/conn/ssl/AndroidDistinguishedNameParser.java
index b2d0e3e..4f0b726 100644
--- a/core/java/org/apache/http/conn/ssl/DistinguishedNameParser.java
+++ b/core/java/org/apache/http/conn/ssl/AndroidDistinguishedNameParser.java
@@ -29,7 +29,7 @@
  * @hide
  */
 @Deprecated
-final class DistinguishedNameParser {
+final class AndroidDistinguishedNameParser {
     private final String dn;
     private final int length;
     private int pos;
@@ -42,7 +42,7 @@
     /** distinguished name chars */
     private char[] chars;
 
-    public DistinguishedNameParser(X500Principal principal) {
+    public AndroidDistinguishedNameParser(X500Principal principal) {
         // RFC2253 is used to ensure we get attributes in the reverse
         // order of the underlying ASN.1 encoding, so that the most
         // significant values of repeated attributes occur first.
diff --git a/core/res/res/layout-sw600dp/date_picker_dialog.xml b/core/res/res/layout-sw600dp/date_picker_dialog.xml
index f9b247f..f18485f 100644
--- a/core/res/res/layout-sw600dp/date_picker_dialog.xml
+++ b/core/res/res/layout-sw600dp/date_picker_dialog.xml
@@ -1,20 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-**
-** Copyright 2007, 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.
-*/
+     Copyright (C) 2007 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.
 -->
 
 <DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
@@ -23,5 +21,4 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:spinnersShown="true"
-    android:calendarViewShown="true"
-    />
+    android:calendarViewShown="true" />
diff --git a/core/res/res/layout/date_picker_dialog.xml b/core/res/res/layout/date_picker_dialog.xml
index db8f311..64ac1b9 100644
--- a/core/res/res/layout/date_picker_dialog.xml
+++ b/core/res/res/layout/date_picker_dialog.xml
@@ -1,20 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-**
-** Copyright 2007, 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.
-*/
+     Copyright (C) 2007 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.
 -->
 
 <DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
@@ -23,5 +21,4 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:spinnersShown="true"
-    android:calendarViewShown="false"
-    />
+    android:calendarViewShown="false" />
diff --git a/core/res/res/layout/date_picker_header_material.xml b/core/res/res/layout/date_picker_header_material.xml
index 821b588..cfc6d0d 100644
--- a/core/res/res/layout/date_picker_header_material.xml
+++ b/core/res/res/layout/date_picker_header_material.xml
@@ -19,35 +19,46 @@
               android:id="@+id/date_picker_header"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
-              android:paddingStart="?attr/dialogPreferredPadding"
-              android:paddingEnd="?attr/dialogPreferredPadding"
-              android:paddingTop="16dp"
-              android:paddingBottom="18dp"
-              android:orientation="vertical"
-              android:clipToPadding="false"
-              android:clipChildren="false">
+              android:orientation="vertical">
 
-    <TextView
-        android:id="@+id/date_picker_header_year"
-        android:layout_width="wrap_content"
+    <ViewStub
+        android:id="@id/topPanel"
+        android:layout="@layout/alert_dialog_title_material"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:focusable="true"
-        android:layout_marginStart="-8dp"
-        android:layout_marginEnd="-8dp"
-        android:layout_marginTop="-8dp"
-        android:layout_marginBottom="-8dp"
-        android:padding="8dp"
-        android:background="?attr/selectableItemBackground"
-        android:textAppearance="@style/TextAppearance.Material.DatePicker.YearLabel"
-        android:nextFocusForward="@+id/prev" />
+        android:paddingStart="?attr/dialogPreferredPadding"
+        android:paddingEnd="?attr/dialogPreferredPadding"
+        android:paddingTop="16dp"
+        android:paddingBottom="18dp"
+        android:orientation="vertical"
+        android:clipToPadding="false"
+        android:clipChildren="false">
 
-    <TextView
-        android:id="@+id/date_picker_header_date"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textAppearance="@style/TextAppearance.Material.DatePicker.DateLabel"
-        android:gravity="start"
-        android:maxLines="2"
-        android:ellipsize="none" />
+        <TextView
+            android:id="@+id/date_picker_header_year"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:focusable="true"
+            android:layout_marginStart="-8dp"
+            android:layout_marginEnd="-8dp"
+            android:layout_marginTop="-8dp"
+            android:layout_marginBottom="-8dp"
+            android:padding="8dp"
+            android:background="?attr/selectableItemBackground"
+            android:textAppearance="@style/TextAppearance.Material.DatePicker.YearLabel"
+            android:nextFocusForward="@+id/prev" />
 
+        <TextView
+            android:id="@+id/date_picker_header_date"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="@style/TextAppearance.Material.DatePicker.DateLabel"
+            android:gravity="start"
+            android:maxLines="2"
+            android:ellipsize="none" />
+    </LinearLayout>
 </LinearLayout>
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 731bf42..961d0eb 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -341,15 +341,9 @@
     <family lang="ko">
         <font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font>
     </family>
-    <family>
-        <font weight="400" style="normal">NanumGothic.ttf</font>
-    </family>
     <family lang="und-Zsye">
         <font weight="400" style="normal">NotoColorEmoji.ttf</font>
     </family>
-    <family>
-        <font weight="400" style="normal">DroidSansFallback.ttf</font>
-    </family>
     <!--
         Tai Le and Mongolian are intentionally kept last, to make sure they don't override
         the East Asian punctuation for Chinese.
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 9fc0c19..c5000e4 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -95,28 +95,21 @@
 void Texture::upload(GLint internalformat, uint32_t width, uint32_t height,
         GLenum format, GLenum type, const void* pixels) {
     GL_CHECKPOINT();
-    bool needsAlloc = updateSize(width, height, internalformat);
-    if (!needsAlloc && !pixels) {
-        return;
-    }
     mCaches.textureState().activateTexture(0);
-    GL_CHECKPOINT();
+    bool needsAlloc = updateSize(width, height, internalformat);
     if (!mId) {
         glGenTextures(1, &mId);
         needsAlloc = true;
     }
-    GL_CHECKPOINT();
     mCaches.textureState().bindTexture(GL_TEXTURE_2D, mId);
-    GL_CHECKPOINT();
     if (needsAlloc) {
         glTexImage2D(GL_TEXTURE_2D, 0, mFormat, mWidth, mHeight, 0,
                 format, type, pixels);
-        GL_CHECKPOINT();
-    } else {
+    } else if (pixels) {
         glTexSubImage2D(GL_TEXTURE_2D, 0, mFormat, mWidth, mHeight, 0,
                 format, type, pixels);
-        GL_CHECKPOINT();
     }
+    GL_CHECKPOINT();
 }
 
 static void uploadToTexture(bool resize, GLenum format, GLenum type, GLsizei stride, GLsizei bpp,
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
index 13105aa..1aec253 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
@@ -635,9 +635,9 @@
             CharSequence description = printer.getDescription();
 
             CharSequence subtitle;
-            if (printServiceLabel == null) {
+            if (TextUtils.isEmpty(printServiceLabel)) {
                 subtitle = description;
-            } else if (description == null) {
+            } else if (TextUtils.isEmpty(description)) {
                 subtitle = printServiceLabel;
             } else {
                 subtitle = getString(R.string.printer_extended_description_template,
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index c634c50..d69250b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -244,14 +244,16 @@
         ComponentName adminComponent = null;
         List<ComponentName> admins = dpm.getActiveAdmins();
         int quality;
-        for (ComponentName admin : admins) {
-            quality = dpm.getPasswordQuality(admin);
-            if (quality >= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
-                if (adminComponent == null) {
-                    adminComponent = admin;
-                } else {
-                    isDisabledByMultipleAdmins = true;
-                    break;
+        if (admins != null) {
+            for (ComponentName admin : admins) {
+                quality = dpm.getPasswordQuality(admin);
+                if (quality >= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+                    if (adminComponent == null) {
+                        adminComponent = admin;
+                    } else {
+                        isDisabledByMultipleAdmins = true;
+                        break;
+                    }
                 }
             }
         }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 6ec757d..c1f97a8 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -152,6 +152,9 @@
     <!-- Needed for passing extras with intent ACTION_SHOW_ADMIN_SUPPORT_DETAILS -->
     <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
 
+    <!-- TV picture-in-picture -->
+    <uses-permission android:name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE" />
+
     <application
         android:name=".SystemUIApplication"
         android:persistent="true"
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
index 2aac69a..3d91d62 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -29,6 +29,7 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -37,6 +38,9 @@
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
+
 /**
  * Manages the picture-in-picture (PIP) UI and states.
  */
@@ -46,10 +50,15 @@
 
     private static PipManager sPipManager;
 
+    private static final int MAX_RUNNING_TASKS_COUNT = 10;
+
     private static final int STATE_NO_PIP = 0;
     private static final int STATE_PIP_OVERLAY = 1;
     private static final int STATE_PIP_MENU = 2;
 
+    private static final int TASK_ID_NO_PIP = -1;
+    private static final int INVALID_RESOURCE_TYPE = -1;
+
     private Context mContext;
     private IActivityManager mActivityManager;
     private int mState = STATE_NO_PIP;
@@ -58,6 +67,8 @@
     private Rect mPipBound;
     private Rect mMenuModePipBound;
     private boolean mInitialized;
+    private int mPipTaskId = TASK_ID_NO_PIP;
+
     private final Runnable mOnActivityPinnedRunnable = new Runnable() {
         @Override
         public void run() {
@@ -74,6 +85,7 @@
             }
             if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
             mState = STATE_PIP_OVERLAY;
+            mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
             launchPipOverlayActivity();
         }
     };
@@ -86,15 +98,27 @@
         }
     };
 
-    private final BroadcastReceiver mPipButtonReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (DEBUG) Log.d(TAG, "PIP button pressed");
-            if (!hasPipTasks()) {
-                startPip();
-            } else if (mState == STATE_PIP_OVERLAY) {
-                showPipMenu();
+            String action = intent.getAction();
+            if (Intent.ACTION_PICTURE_IN_PICTURE_BUTTON.equals(action)) {
+                if (DEBUG) Log.d(TAG, "PIP button pressed");
+                if (!hasPipTasks()) {
+                    startPip();
+                } else if (mState == STATE_PIP_OVERLAY) {
+                    showPipMenu();
+                }
+            } else if (Intent.ACTION_MEDIA_RESOURCE_GRANTED.equals(action)) {
+                String[] packageNames = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
+                int resourceType = intent.getIntExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE,
+                        INVALID_RESOURCE_TYPE);
+                if (mState != STATE_NO_PIP && packageNames != null && packageNames.length > 0
+                        && resourceType == Intent.EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC) {
+                    handleMediaResourceGranted(packageNames);
+                }
             }
+
         }
     };
 
@@ -125,7 +149,8 @@
         }
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_PICTURE_IN_PICTURE_BUTTON);
-        mContext.registerReceiver(mPipButtonReceiver, intentFilter);
+        intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
     }
 
     private void startPip() {
@@ -142,6 +167,7 @@
      */
     public void closePip() {
         mState = STATE_NO_PIP;
+        mPipTaskId = TASK_ID_NO_PIP;
         StackInfo stackInfo = null;
         try {
             stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
@@ -166,6 +192,7 @@
      */
     public void movePipToFullscreen() {
         mState = STATE_NO_PIP;
+        mPipTaskId = TASK_ID_NO_PIP;
         for (int i = mListeners.size() - 1; i >= 0; --i) {
             mListeners.get(i).onMoveToFullscreen();
         }
@@ -251,6 +278,45 @@
         }
     }
 
+    private void handleMediaResourceGranted(String[] packageNames) {
+        StackInfo fullscreenStack = null;
+        try {
+            fullscreenStack = mActivityManager.getStackInfo(FULLSCREEN_WORKSPACE_STACK_ID);
+        } catch (RemoteException e) {
+            Log.e(TAG, "getStackInfo failed", e);
+        }
+        if (fullscreenStack == null) {
+            return;
+        }
+        int fullscreenTopTaskId = fullscreenStack.taskIds[fullscreenStack.taskIds.length - 1];
+        List<RunningTaskInfo> tasks = null;
+        try {
+            tasks = mActivityManager.getTasks(MAX_RUNNING_TASKS_COUNT, 0);
+        } catch (RemoteException e) {
+            Log.e(TAG, "getTasks failed", e);
+        }
+        if (tasks == null) {
+            return;
+        }
+        boolean wasGrantedInFullscreen = false;
+        boolean wasGrantedInPip = false;
+        for (int i = tasks.size() - 1; i >= 0; --i) {
+            RunningTaskInfo task = tasks.get(i);
+            for (int j = packageNames.length - 1; j >= 0; --j) {
+                if (task.topActivity.getPackageName().equals(packageNames[j])) {
+                    if (task.id == fullscreenTopTaskId) {
+                        wasGrantedInFullscreen = true;
+                    } else if (task.id == mPipTaskId) {
+                        wasGrantedInPip= true;
+                    }
+                }
+            }
+        }
+        if (wasGrantedInFullscreen && !wasGrantedInPip) {
+            closePip();
+        }
+    }
+
     private class TaskStackListener extends ITaskStackListener.Stub {
         @Override
         public void onTaskStackChanged() throws RemoteException {