Clean up package installer styling

Package installer should be using exclusively the device
defaut themes on handhelds (phones and tables) to allow
OEMs customize its look and feel. Also for handhelds the
installer should use the same preference framework as the
settings app to ensure it looks like the settings app on
an OEMs device.

This change needs to be picked up by a GMS build to deliver
to partners ensuring the installer UI is consistent with
the device UI.

bug:24286616

Change-Id: I92e39fd1488e76b0b23b7f1efa13e04ed5bbc7ba
diff --git a/res/drawable/header_background.xml b/res/drawable/header_background.xml
deleted file mode 100644
index 77db9e0..0000000
--- a/res/drawable/header_background.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="?android:attr/colorControlHighlight">
-    <item android:drawable="@color/header_background_color" />
-</ripple>
-
diff --git a/res/drawable/ic_dialog_alert_material.xml b/res/drawable/ic_dialog_alert_material.xml
new file mode 100644
index 0000000..8bd2e0b
--- /dev/null
+++ b/res/drawable/ic_dialog_alert_material.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2014 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="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?attr/colorControlNormal">
+    <path
+        android:pathData="M1,21l22,0L12,2L1,21zM13,18l-2,0l0,-2l2,0L13,18zM13,14l-2,0l0,-4l2,0L13,14z"
+        android:fillColor="@android:color/white"/>
+</vector>
diff --git a/res/drawable/ic_more_items.xml b/res/drawable/ic_more_items.xml
new file mode 100644
index 0000000..5fdcdce
--- /dev/null
+++ b/res/drawable/ic_more_items.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    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="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#000000"
+        android:pathData="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7
+7v2h14V7H7z" />
+    <path
+        android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/res/layout/app_details.xml b/res/layout/app_details.xml
index 6a330c7..8f7d2cf 100644
--- a/res/layout/app_details.xml
+++ b/res/layout/app_details.xml
@@ -4,9 +4,9 @@
      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.
@@ -32,7 +32,7 @@
         android:layout_width="32dip"
         android:layout_height="32dip"
         android:layout_marginStart="8dip"
-        android:background="@color/transparent"
+        android:background="@android:color/transparent"
         android:layout_alignParentStart="true"
         android:gravity="start"
         android:scaleType="centerCrop"/>
@@ -61,6 +61,6 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
     </FrameLayout>
-    
+
 </RelativeLayout>
 
diff --git a/res/layout/grant_permissions.xml b/res/layout/grant_permissions.xml
index b356524..086a541 100644
--- a/res/layout/grant_permissions.xml
+++ b/res/layout/grant_permissions.xml
@@ -18,6 +18,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent" >
+
     <LinearLayout
         android:id="@+id/dialog_container"
         android:layout_width="fill_parent"
@@ -46,7 +47,7 @@
             android:visibility="gone">
         </CheckBox>
 
-        <com.android.internal.widget.ButtonBarLayout
+        <com.android.packageinstaller.permission.ui.ButtonBarLayout
             android:id="@+id/button_group"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -62,8 +63,8 @@
                 android:paddingBottom="4dp"
                 android:paddingEnd="12dp"
                 android:singleLine="true"
-                style="@android:style/TextAppearance.Material.Body2"
-                android:textColor="@color/grant_permissions_progress_color"
+                style="?android:attr/textAppearanceSmall"
+                android:textColor="?android:attr/textColorSecondary"
                 android:visibility="invisible">
             </TextView>
 
@@ -72,14 +73,16 @@
                 android:layout_width="0dp"
                 android:layout_height="0dp"
                 android:layout_weight="1"
-                android:visibility="invisible" />
+                android:visibility="invisible" >
+            </Space>
 
             <Button
                 android:id="@+id/permission_deny_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 style="?android:attr/buttonBarButtonStyle"
-                android:text="@string/grant_dialog_button_deny" />
+                android:text="@string/grant_dialog_button_deny" >
+            </Button>
 
             <Button
                 android:id="@+id/permission_allow_button"
@@ -87,9 +90,11 @@
                 android:layout_height="wrap_content"
                 style="?android:attr/buttonBarButtonStyle"
                 android:layout_marginStart="8dip"
-                android:text="@string/grant_dialog_button_allow" />
+                android:text="@string/grant_dialog_button_allow" >
+            </Button>
 
-        </com.android.internal.widget.ButtonBarLayout>
+        </com.android.packageinstaller.permission.ui.ButtonBarLayout>
 
     </LinearLayout>
+
 </com.android.packageinstaller.permission.ui.ManualLayoutFrame>
diff --git a/res/layout/header.xml b/res/layout/header.xml
index 0e000a4..f158e44 100644
--- a/res/layout/header.xml
+++ b/res/layout/header.xml
@@ -17,9 +17,8 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="?android:attr/actionBarSize"
-    android:background="@drawable/header_background"
-    android:gravity="center_vertical"
-    android:theme="@style/Theme.Header.Settings" >
+    android:background="?android:attr/colorPrimary"
+    android:gravity="center_vertical" >
 
     <ImageView android:id="@+id/icon"
         android:layout_width="@dimen/header_subsettings_margin_start"
@@ -31,12 +30,11 @@
         android:id="@+id/name"
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
-        android:layout_toStartOf="@+id/app_settings"
         android:layout_marginStart="@dimen/header_subsettings_margin_start"
         android:layout_alignWithParentIfMissing="true"
         android:layout_centerVertical="true"
         android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textColor="@android:color/white"
+        android:textColor="?android:attr/textColorPrimaryInverse"
         android:textAlignment="viewStart" />
 
     <ImageView
@@ -52,11 +50,4 @@
         android:src="@drawable/ic_info"
         style="?android:attr/borderlessButtonStyle" />
 
-    <View
-        android:id="@+id/row_divider"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:background="?android:attr/listDivider" />
-
 </RelativeLayout>
-
diff --git a/res/layout/install_confirm.xml b/res/layout/install_confirm.xml
index 86ea165..72d5e37 100644
--- a/res/layout/install_confirm.xml
+++ b/res/layout/install_confirm.xml
@@ -31,9 +31,10 @@
             android:id="@+id/install_confirm_question"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:paddingStart="16dip"
+            android:paddingEnd="16dip"
             android:text="@string/install_confirm_question"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            style="@style/padded"
             android:paddingTop="4dip" />
 
     <ImageView
diff --git a/res/layout/permission_description.xml b/res/layout/permission_description.xml
index 3f1cf43..c9b60d6 100644
--- a/res/layout/permission_description.xml
+++ b/res/layout/permission_description.xml
@@ -26,15 +26,14 @@
         android:layout_height="36dip"
         android:layout_marginTop="3dp"
         android:tint="?android:attr/colorAccent"
-        android:scaleType="fitCenter" />
+        android:scaleType="fitCenter" >
+    </ImageView>
 
     <TextView
         android:id="@+id/permission_message"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_toRightOf="@id/permission_icon"
-        android:lineSpacingMultiplier="1.024"
-        android:fontFamily="@*android:string/font_family_body_2_material"
         android:paddingStart="16dip"
         android:paddingEnd="8dip"
         style="?android:attr/textAppearanceMedium">
diff --git a/res/layout/permissions_frame.xml b/res/layout/permissions_frame.xml
index 8f1f278..156af57 100644
--- a/res/layout/permissions_frame.xml
+++ b/res/layout/permissions_frame.xml
@@ -30,8 +30,8 @@
             android:layout_height="match_parent"
             android:text="@string/no_permissions"
             android:gravity="center"
-            android:textAppearance="@android:style/TextAppearance.Large"
-            />
+            style="?android:attr/textAppearanceLarge">
+        </TextView>
 
     </FrameLayout>
 
diff --git a/res/layout/preference_permissions.xml b/res/layout/preference_permissions.xml
index 67b4469..631d56b 100644
--- a/res/layout/preference_permissions.xml
+++ b/res/layout/preference_permissions.xml
@@ -37,7 +37,7 @@
         android:paddingEnd="20dp"
         android:paddingTop="4dp"
         android:paddingBottom="4dp">
-        <com.android.internal.widget.PreferenceImageView
+        <com.android.packageinstaller.permission.ui.PreferenceImageView
             android:id="@android:id/icon"
             android:layout_width="24dp"
             android:layout_height="24dp"
diff --git a/res/layout/preference_permissions_switch.xml b/res/layout/preference_permissions_switch.xml
index cf444d9..78d2a4e 100644
--- a/res/layout/preference_permissions_switch.xml
+++ b/res/layout/preference_permissions_switch.xml
@@ -37,7 +37,7 @@
         android:paddingEnd="20dp"
         android:paddingTop="4dp"
         android:paddingBottom="4dp">
-        <com.android.internal.widget.PreferenceImageView
+        <com.android.packageinstaller.permission.ui.PreferenceImageView
             android:id="@android:id/icon"
             android:layout_width="36dp"
             android:layout_height="36dp"
diff --git a/res/layout/uninstall_confirm.xml b/res/layout/uninstall_confirm.xml
index f604023..78270f6 100644
--- a/res/layout/uninstall_confirm.xml
+++ b/res/layout/uninstall_confirm.xml
@@ -40,9 +40,10 @@
             android:id="@+id/activity_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:paddingStart="16dip"
+            android:paddingEnd="16dip"
             android:textColor="?android:attr/textColorSecondary"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            style="@style/padded"
             android:visibility="gone" />
 
         <!-- The snippet (title & icon) about the application being uninstalled. -->
diff --git a/res/values-television/colors.xml b/res/values-television/colors.xml
index eb6bfa7..0820960 100644
--- a/res/values-television/colors.xml
+++ b/res/values-television/colors.xml
@@ -15,6 +15,13 @@
 -->
 
 <resources>
+
+    <color name="lb_content_title_text_color">#FFF1F1F1</color>
+    <color name="lb_content_breadcrumb_text_color">#88F1F1F1</color>
+    <color name="lb_content_description_text_color">#88F1F1F1</color>
+    <color name="lb_action_fragment_background">#FF111111</color>
+    <color name="lb_dialog_activity_background">#77000000</color>
+
     <color name="grant_permissions_background_color">#ff263238</color>
     <color name="grant_permissions_app_color">@color/grant_permissions_white_text_alpha_100</color>
     <color name="grant_permissions_progress_color">@color/grant_permissions_white_text_alpha_100</color>
diff --git a/res/values-television/styles.xml b/res/values-television/styles.xml
new file mode 100644
index 0000000..5f712f7
--- /dev/null
+++ b/res/values-television/styles.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+
+    <style name="PreferenceThemeOverlay.v14.Permissions">
+        <item name="preferenceStyle">@style/Preference.Permissions</item>
+        <item name="preferenceCategoryStyle">@style/Preference.Category.Permissions</item>
+        <item name="switchPreferenceStyle">@style/Preference.SwitchPreference.Permissions</item>
+    </style>
+
+    <style name="Preference.Permissions">
+        <item name="layout">@layout/preference_permissions</item>
+    </style>
+
+    <style name="Preference.Category.Permissions">
+        <item name="layout">@layout/preference_category_material</item>
+    </style>
+
+    <style name="Preference.SwitchPreference.Permissions">
+        <item name="layout">@layout/preference_permissions_switch</item>
+    </style>
+
+</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
deleted file mode 100755
index 549f55f..0000000
--- a/res/values/colors.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<resources>
-    <color name="shadow">#cc222222</color>
-    <color name="transparent">#00000000</color>
-    <color name="header_background_color">#ff37474f</color>
-    <color name="grant_permissions_app_color">@*android:color/primary_text_default_material_light</color>
-    <color name="grant_permissions_progress_color">#60000000</color>
-
-    <color name="lb_content_title_text_color">#FFF1F1F1</color>
-    <color name="lb_content_breadcrumb_text_color">#88F1F1F1</color>
-    <color name="lb_content_description_text_color">#88F1F1F1</color>
-    <color name="lb_action_fragment_background">#FF111111</color>
-    <color name="lb_dialog_activity_background">#77000000</color>
-
-</resources>
-
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 9c16697..7f6a469 100755
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -15,37 +15,22 @@
 -->
 
 <resources>
-    <style name="padded">
-        <item name="android:paddingStart">16dip</item>
-        <item name="android:paddingEnd">16dip</item>
+
+    <style name="Theme.DialogWhenLarge"
+           parent="@android:style/Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar">
     </style>
-    <style name="Theme.DialogWhenLarge" parent="@android:style/Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar"/>
-    <style name="Theme.AlertDialogActivity" parent="@android:style/Theme.DeviceDefault.Light.Panel">
+
+    <style name="Theme.AlertDialogActivity"
+           parent="@android:style/Theme.DeviceDefault.Light.Panel">
         <item name="android:backgroundDimEnabled">true</item>
     </style>
 
-    <style name="Theme.Header.Settings" parent="@android:style/Theme.DeviceDefault.Settings">
-    </style>
-
-    <style name="PreferenceThemeOverlay.v14.Permissions">
-        <item name="preferenceStyle">@style/Preference.Permissions</item>
-        <item name="preferenceCategoryStyle">@style/Preference.Category.Permissions</item>
-        <item name="switchPreferenceStyle">@style/Preference.SwitchPreference.Permissions</item>
-    </style>
-
-    <style name="Preference.Permissions">
-        <item name="layout">@layout/preference_permissions</item>
-    </style>
-
-    <style name="Preference.Category.Permissions">
-        <item name="layout">@layout/preference_category_material</item>
-    </style>
-
-    <style name="Preference.SwitchPreference.Permissions">
-        <item name="layout">@layout/preference_permissions_switch</item>
+    <style name="Theme.Header.Settings"
+           parent="@android:style/Theme.DeviceDefault.Settings">
     </style>
 
     <style name="ActionBar" parent="@android:style/Widget.Material.ActionBar.Solid">
         <item name="android:contentInsetStart">72dp</item>
     </style>
+
 </resources>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 2f9c2b5..026c77f 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -16,11 +16,13 @@
   -->
 
 <resources>
-    <style name="Settings" parent="@android:style/Theme.DeviceDefault.Settings">
-        <item name="android:actionBarStyle">@style/ActionBar</item>
-        <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Permissions</item>
+
+    <style name="Settings"
+           parent="@android:style/Theme.DeviceDefault.Settings">
     </style>
 
     <style name="GrantPermissions"
-            parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar" />
+           parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar">
+    </style>
+
 </resources>
diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java
index 9365bf1..e5d96d5 100644
--- a/src/com/android/packageinstaller/permission/model/PermissionApps.java
+++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java
@@ -31,6 +31,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import com.android.packageinstaller.R;
 import com.android.packageinstaller.permission.utils.Utils;
 
 import java.util.ArrayList;
@@ -275,7 +276,7 @@
         if (info.icon != 0) {
             mIcon = info.loadUnbadgedIcon(mPm);
         } else {
-            mIcon = mContext.getDrawable(com.android.internal.R.drawable.ic_perm_device_info);
+            mIcon = mContext.getDrawable(R.drawable.ic_perm_device_info);
         }
         mIcon = Utils.applyTint(mContext, mIcon, android.R.attr.colorControlNormal);
     }
diff --git a/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java b/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java
new file mode 100644
index 0000000..59e5470
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java
@@ -0,0 +1,117 @@
+/*
+ * 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.packageinstaller.permission.ui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.LinearLayout;
+import com.android.packageinstaller.R;
+
+/**
+ * An extension of LinearLayout that automatically switches to vertical
+ * orientation when it can't fit its child views horizontally.
+ */
+public class ButtonBarLayout extends LinearLayout {
+    /** Whether the current configuration allows stacking. */
+    private boolean mAllowStacking;
+
+    private int mLastWidthSize = -1;
+
+    public ButtonBarLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mAllowStacking = true;
+    }
+
+    public void setAllowStacking(boolean allowStacking) {
+        if (mAllowStacking != allowStacking) {
+            mAllowStacking = allowStacking;
+            if (!mAllowStacking && getOrientation() == LinearLayout.VERTICAL) {
+                setStacked(false);
+            }
+            requestLayout();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+
+        if (mAllowStacking) {
+            if (widthSize > mLastWidthSize && isStacked()) {
+                // We're being measured wider this time, try un-stacking.
+                setStacked(false);
+            }
+
+            mLastWidthSize = widthSize;
+        }
+
+        boolean needsRemeasure = false;
+
+        // If we're not stacked, make sure the measure spec is AT_MOST rather
+        // than EXACTLY. This ensures that we'll still get TOO_SMALL so that we
+        // know to stack the buttons.
+        final int initialWidthMeasureSpec;
+        if (!isStacked() && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
+            initialWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);
+
+            // We'll need to remeasure again to fill excess space.
+            needsRemeasure = true;
+        } else {
+            initialWidthMeasureSpec = widthMeasureSpec;
+        }
+
+        super.onMeasure(initialWidthMeasureSpec, heightMeasureSpec);
+
+        if (mAllowStacking && !isStacked()) {
+            final int measuredWidth = getMeasuredWidthAndState();
+            final int measuredWidthState = measuredWidth & MEASURED_STATE_MASK;
+            if (measuredWidthState == MEASURED_STATE_TOO_SMALL) {
+                setStacked(true);
+
+                // Measure again in the new orientation.
+                needsRemeasure = true;
+            }
+        }
+
+        if (needsRemeasure) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+    }
+
+    private void setStacked(boolean stacked) {
+        setOrientation(stacked ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
+        setGravity(stacked ? Gravity.RIGHT : Gravity.BOTTOM);
+
+        final View spacer = findViewById(R.id.spacer);
+        if (spacer != null) {
+            spacer.setVisibility(stacked ? View.GONE : View.INVISIBLE);
+        }
+
+        // Reverse the child order. This is specific to the Material button
+        // bar's layout XML and will probably not generalize.
+        final int childCount = getChildCount();
+        for (int i = childCount - 2; i >= 0; i--) {
+            bringChildToFront(getChildAt(i));
+        }
+    }
+
+    private boolean isStacked() {
+        return getOrientation() == LinearLayout.VERTICAL;
+    }
+}
diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java
index aaa65f9..44bbcc9 100644
--- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java
+++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java
@@ -26,11 +26,12 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PermissionInfo;
 import android.content.res.Resources;
+import android.graphics.Typeface;
 import android.graphics.drawable.Icon;
 import android.hardware.camera2.utils.ArrayUtils;
 import android.os.Bundle;
 import android.text.SpannableString;
-import android.text.style.ForegroundColorSpan;
+import android.text.style.StyleSpan;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -72,9 +73,11 @@
         setTitle(R.string.permission_request_title);
 
         if (Utils.isTelevision(this)) {
-            mViewHandler = new GrantPermissionsTvViewHandler(this).setResultListener(this);
+            mViewHandler = new com.android.packageinstaller.permission.ui.television
+                    .GrantPermissionsViewHandlerImpl(this).setResultListener(this);
         } else {
-            mViewHandler = new GrantPermissionsDefaultViewHandler(this).setResultListener(this);
+            mViewHandler = new com.android.packageinstaller.permission.ui.handheld
+                    .GrantPermissionsViewHandlerImpl(this).setResultListener(this);
         }
 
         mRequestedPermissions = getIntent().getStringArrayExtra(
@@ -190,8 +193,7 @@
                 // Color the app name.
                 int appLabelStart = message.toString().indexOf(appLabel.toString(), 0);
                 int appLabelLength = appLabel.length();
-                int color = getColor(R.color.grant_permissions_app_color);
-                message.setSpan(new ForegroundColorSpan(color), appLabelStart,
+                message.setSpan(new StyleSpan(Typeface.BOLD), appLabelStart,
                         appLabelStart + appLabelLength, 0);
 
                 // Set the new grant view
diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsViewHandler.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsViewHandler.java
index 4032abb..5e2259a 100644
--- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsViewHandler.java
+++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsViewHandler.java
@@ -25,7 +25,7 @@
  * Class for managing the presentation and user interaction of the "grant
  * permissions" user interface.
  */
-interface GrantPermissionsViewHandler {
+public interface GrantPermissionsViewHandler {
 
     /**
      * Listener interface for getting notified when the user responds to a
diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java
index 8ba6b12..f570356 100644
--- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java
+++ b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.Log;
+import com.android.packageinstaller.permission.utils.Utils;
 
 public final class ManagePermissionsActivity extends OverlayTouchActivity {
     private static final String LOG_TAG = "ManagePermissionsActivity";
@@ -37,7 +38,13 @@
 
         switch (action) {
             case Intent.ACTION_MANAGE_PERMISSIONS: {
-                fragment = ManagePermissionsFragment.newInstance();
+                if (Utils.isTelevision(this)) {
+                    fragment = com.android.packageinstaller.permission.ui.television
+                            .ManagePermissionsFragment.newInstance();
+                } else {
+                    fragment = com.android.packageinstaller.permission.ui.handheld
+                            .ManagePermissionsFragment.newInstance();
+                }
             } break;
 
             case Intent.ACTION_MANAGE_APP_PERMISSIONS: {
@@ -47,7 +54,13 @@
                     finish();
                     return;
                 }
-                fragment = AppPermissionsFragment.newInstance(packageName);
+                if (Utils.isTelevision(this)) {
+                    fragment = com.android.packageinstaller.permission.ui.television
+                            .AppPermissionsFragment.newInstance(packageName);
+                } else {
+                    fragment = com.android.packageinstaller.permission.ui.handheld
+                            .AppPermissionsFragment.newInstance(packageName);
+                }
             } break;
 
             case Intent.ACTION_MANAGE_PERMISSION_APPS: {
@@ -57,7 +70,13 @@
                     finish();
                     return;
                 }
-                fragment = PermissionAppsFragment.newInstance(permissionName);
+                if (Utils.isTelevision(this)) {
+                    fragment = com.android.packageinstaller.permission.ui.television
+                            .PermissionAppsFragment.newInstance(permissionName);
+                } else {
+                    fragment = com.android.packageinstaller.permission.ui.handheld
+                            .PermissionAppsFragment.newInstance(permissionName);
+                }
             } break;
 
             default: {
diff --git a/src/com/android/packageinstaller/permission/ui/OverlayWarningDialog.java b/src/com/android/packageinstaller/permission/ui/OverlayWarningDialog.java
index a7c1e2a..61734b4 100644
--- a/src/com/android/packageinstaller/permission/ui/OverlayWarningDialog.java
+++ b/src/com/android/packageinstaller/permission/ui/OverlayWarningDialog.java
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.packageinstaller.permission.ui;
 
 import android.app.Activity;
diff --git a/src/com/android/packageinstaller/permission/ui/PreferenceImageView.java b/src/com/android/packageinstaller/permission/ui/PreferenceImageView.java
new file mode 100644
index 0000000..c3f5167
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/ui/PreferenceImageView.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 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.packageinstaller.permission.ui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+/**
+ * Extension of ImageView that correctly applies maxWidth and maxHeight.
+ */
+public class PreferenceImageView extends ImageView {
+
+    public PreferenceImageView(Context context) {
+        this(context, null);
+    }
+
+    public PreferenceImageView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public PreferenceImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public PreferenceImageView(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED) {
+            final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+            final int maxWidth = getMaxWidth();
+            if (maxWidth != Integer.MAX_VALUE
+                    && (maxWidth < widthSize || widthMode == MeasureSpec.UNSPECIFIED)) {
+                widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST);
+            }
+        }
+
+        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        if (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED) {
+            final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+            final int maxHeight = getMaxHeight();
+            if (maxHeight != Integer.MAX_VALUE
+                    && (maxHeight < heightSize || heightMode == MeasureSpec.UNSPECIFIED)) {
+                heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
+            }
+        }
+
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+}
diff --git a/src/com/android/packageinstaller/permission/ui/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java
similarity index 94%
copy from src/com/android/packageinstaller/permission/ui/AllAppPermissionsFragment.java
copy to src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java
index 2fb9a51..b3b0895 100644
--- a/src/com/android/packageinstaller/permission/ui/AllAppPermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java
@@ -14,7 +14,7 @@
 * limitations under the License.
 */
 
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.handheld;
 
 import android.app.ActionBar;
 import android.app.AlertDialog;
@@ -29,14 +29,13 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceGroup;
 import android.provider.Settings;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceGroup;
 import android.util.Log;
 import android.view.MenuItem;
-
 import com.android.packageinstaller.R;
 import com.android.packageinstaller.permission.utils.Utils;
 
@@ -178,7 +177,6 @@
         if (pref == null) {
             pref = new PreferenceCategory(getContext());
             pref.setKey(group.name);
-            pref.setLayoutResource(R.layout.preference_category_material);
             pref.setTitle(group.loadLabel(pm));
             prefs.add(pref);
             getPreferenceScreen().addPreference(pref);
@@ -189,7 +187,6 @@
     private Preference getPreference(PermissionInfo perm, PermissionGroupInfo group,
             PackageManager pm) {
         Preference pref = new Preference(getContext());
-        pref.setLayoutResource(R.layout.preference_permissions);
         Drawable icon = null;
         if (perm.icon != 0) {
             icon = perm.loadIcon(pm);
diff --git a/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java
similarity index 95%
copy from src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java
copy to src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java
index 6396c61..f56cba7 100644
--- a/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java
@@ -14,7 +14,7 @@
 * limitations under the License.
 */
 
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.handheld;
 
 import android.annotation.Nullable;
 import android.app.ActionBar;
@@ -31,12 +31,12 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceScreen;
+import android.preference.SwitchPreference;
 import android.provider.Settings;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceScreen;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -46,10 +46,10 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 import android.widget.Toast;
-
 import com.android.packageinstaller.R;
 import com.android.packageinstaller.permission.model.AppPermissionGroup;
 import com.android.packageinstaller.permission.model.AppPermissions;
+import com.android.packageinstaller.permission.ui.OverlayTouchActivity;
 import com.android.packageinstaller.permission.utils.LocationUtils;
 import com.android.packageinstaller.permission.utils.SafetyNetLogger;
 import com.android.packageinstaller.permission.utils.Utils;
@@ -188,12 +188,17 @@
     }
 
     private void loadPreferences() {
-        Context context = getPreferenceManager().getContext();
+        Context context = getActivity();
         if (context == null) {
             return;
         }
 
         PreferenceScreen screen = getPreferenceScreen();
+        if (screen == null) {
+            screen = getPreferenceManager().createPreferenceScreen(getActivity());
+            setPreferenceScreen(screen);
+        }
+
         screen.removeAll();
 
         if (mExtraScreen != null) {
@@ -376,10 +381,6 @@
             super.onCreate(savedInstanceState);
             setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel, mOuterFragment.mInfoIntent);
             setHasOptionsMenu(true);
-        }
-
-        @Override
-        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
             setPreferenceScreen(mOuterFragment.mExtraScreen);
         }
 
diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java b/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java
similarity index 96%
rename from src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java
rename to src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java
index c5d7878..2d27f06 100644
--- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.handheld;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -40,12 +40,14 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import com.android.internal.widget.ButtonBarLayout;
 import com.android.packageinstaller.R;
+import com.android.packageinstaller.permission.ui.ButtonBarLayout;
+import com.android.packageinstaller.permission.ui.GrantPermissionsViewHandler;
+import com.android.packageinstaller.permission.ui.ManualLayoutFrame;
 
 import java.util.ArrayList;
 
-final class GrantPermissionsDefaultViewHandler
+public final class GrantPermissionsViewHandlerImpl
         implements GrantPermissionsViewHandler, OnClickListener {
 
     public static final String ARG_GROUP_NAME = "ARG_GROUP_NAME";
@@ -101,12 +103,12 @@
         }
     };
 
-    GrantPermissionsDefaultViewHandler(Context context) {
+    public GrantPermissionsViewHandlerImpl(Context context) {
         mContext = context;
     }
 
     @Override
-    public GrantPermissionsDefaultViewHandler setResultListener(ResultListener listener) {
+    public GrantPermissionsViewHandlerImpl setResultListener(ResultListener listener) {
         mResultListener = listener;
         return this;
     }
@@ -314,9 +316,7 @@
     public View createView() {
         mRootView = (ManualLayoutFrame) LayoutInflater.from(mContext)
                 .inflate(R.layout.grant_permissions, null);
-        ((ButtonBarLayout) mRootView.findViewById(R.id.button_group)).setAllowStacking(
-                Resources.getSystem().getBoolean(
-                        com.android.internal.R.bool.allow_stacked_button_bar));
+        ((ButtonBarLayout) mRootView.findViewById(R.id.button_group)).setAllowStacking(true);
 
         mDialogContainer = (ViewGroup) mRootView.findViewById(R.id.dialog_container);
         mMessageView = (TextView) mRootView.findViewById(R.id.permission_message);
diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java
similarity index 95%
copy from src/com/android/packageinstaller/permission/ui/ManagePermissionsFragment.java
copy to src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java
index e5e06e0..c53da87 100644
--- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.handheld;
 
 import android.annotation.Nullable;
 import android.app.ActionBar;
@@ -23,16 +23,15 @@
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceScreen;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceScreen;
 import android.util.ArraySet;
 import android.util.Log;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
-
 import com.android.packageinstaller.R;
 import com.android.packageinstaller.permission.model.PermissionApps;
 import com.android.packageinstaller.permission.model.PermissionApps.PmCache;
@@ -43,7 +42,8 @@
 import java.util.List;
 
 public final class ManagePermissionsFragment extends PermissionsFrameFragment
-        implements PermissionGroups.PermissionsGroupsChangeCallback, OnPreferenceClickListener {
+        implements PermissionGroups.PermissionsGroupsChangeCallback,
+        Preference.OnPreferenceClickListener {
     private static final String LOG_TAG = "ManagePermissionsFragment";
 
     private static final String OS_PKG = "android";
@@ -144,13 +144,17 @@
     }
 
     private void updatePermissionsUi() {
-        Context context = getPreferenceManager().getContext();
+        Context context = getActivity();
         if (context == null) {
             return;
         }
 
         List<PermissionGroup> groups = mPermissions.getGroups();
         PreferenceScreen screen = getPreferenceScreen();
+        if (screen == null) {
+            screen = getPreferenceManager().createPreferenceScreen(getActivity());
+            setPreferenceScreen(screen);
+        }
 
         // Use this to speed up getting the info for all of the PermissionApps below.
         // Create a new one for each refresh to make sure it has fresh data.
@@ -202,7 +206,7 @@
             Preference extraScreenPreference = new Preference(context);
             extraScreenPreference.setKey(EXTRA_PREFS_KEY);
             extraScreenPreference.setIcon(Utils.applyTint(context,
-                    com.android.internal.R.drawable.ic_more_items,
+                    R.drawable.ic_more_items,
                     android.R.attr.colorControlNormal));
             extraScreenPreference.setTitle(R.string.additional_permissions);
             extraScreenPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@@ -234,6 +238,9 @@
             super.onCreate(icicle);
             getActivity().setTitle(R.string.additional_permissions);
             setHasOptionsMenu(true);
+
+            setPreferenceScreen(((ManagePermissionsFragment) getTargetFragment()).mExtraScreen);
+            setLoading(false /* loading */, true /* animate */);
         }
 
         @Override
@@ -257,11 +264,5 @@
             super.onViewCreated(view, savedInstanceState);
             bindPermissionUi(getActivity(), getView());
         }
-
-        @Override
-        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-            setPreferenceScreen(((ManagePermissionsFragment) getTargetFragment()).mExtraScreen);
-            setLoading(false /* loading */, true /* animate */);
-        }
     }
 }
diff --git a/src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java
similarity index 95%
copy from src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java
copy to src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java
index 8dacd03..554830a 100644
--- a/src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.handheld;
 
 import android.app.ActionBar;
 import android.app.AlertDialog;
@@ -24,12 +24,11 @@
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v4.util.ArrayMap;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceScreen;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceScreen;
+import android.preference.SwitchPreference;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -38,12 +37,12 @@
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
-
 import com.android.packageinstaller.R;
 import com.android.packageinstaller.permission.model.AppPermissionGroup;
 import com.android.packageinstaller.permission.model.PermissionApps;
 import com.android.packageinstaller.permission.model.PermissionApps.Callback;
 import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp;
+import com.android.packageinstaller.permission.ui.OverlayTouchActivity;
 import com.android.packageinstaller.permission.utils.LocationUtils;
 import com.android.packageinstaller.permission.utils.SafetyNetLogger;
 import com.android.packageinstaller.permission.utils.Utils;
@@ -52,7 +51,7 @@
 import java.util.List;
 
 public final class PermissionAppsFragment extends PermissionsFrameFragment implements Callback,
-        OnPreferenceChangeListener {
+        Preference.OnPreferenceChangeListener {
 
     private static final int MENU_SHOW_SYSTEM = Menu.FIRST;
     private static final int MENU_HIDE_SYSTEM = Menu.FIRST + 1;
@@ -138,11 +137,6 @@
     }
 
     @Override
-    protected void onSetEmptyText(TextView textView) {
-        textView.setText(R.string.no_apps);
-    }
-
-    @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         bindUi(this, mPermissionApps);
@@ -179,7 +173,7 @@
 
     @Override
     public void onPermissionsLoaded(PermissionApps permissionApps) {
-        Context context = getPreferenceManager().getContext();
+        Context context = getActivity();
 
         if (context == null) {
             return;
@@ -187,6 +181,10 @@
 
         boolean isTelevision = Utils.isTelevision(context);
         PreferenceScreen screen = getPreferenceScreen();
+        if (screen == null) {
+            screen = getPreferenceManager().createPreferenceScreen(getActivity());
+            setPreferenceScreen(screen);
+        }
 
         ArraySet<String> preferencesToRemove = new ArraySet<>();
         for (int i = 0, n = screen.getPreferenceCount(); i < n; i++) {
@@ -400,10 +398,6 @@
             mOuterFragment = (PermissionAppsFragment) getTargetFragment();
             setLoading(true /* loading */, false /* animate */);
             super.onCreate(savedInstanceState);
-        }
-
-        @Override
-        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
             if (mOuterFragment.mExtraScreen != null) {
                 setPreferenceScreen();
             } else {
diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java
new file mode 100644
index 0000000..e7f63b2
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java
@@ -0,0 +1,121 @@
+/*
+ * 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.packageinstaller.permission.ui.handheld;
+
+import android.os.Bundle;
+import android.preference.PreferenceFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
+import android.view.animation.AnimationUtils;
+import android.widget.ListView;
+import android.widget.TextView;
+import com.android.packageinstaller.R;
+
+public abstract class PermissionsFrameFragment extends PreferenceFragment {
+    private ViewGroup mPreferencesContainer;
+
+    private View mLoadingView;
+    private ViewGroup mPrefsView;
+    private boolean mIsLoading;
+
+    /**
+     * Returns the view group that holds the preferences objects. This will
+     * only be set after {@link #onCreateView} has been called.
+     */
+    protected final ViewGroup getPreferencesContainer() {
+        return mPreferencesContainer;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.permissions_frame, container,
+                        false);
+        mPrefsView = (ViewGroup) rootView.findViewById(R.id.prefs_container);
+        if (mPrefsView == null) {
+            mPrefsView = rootView;
+        }
+        mLoadingView = rootView.findViewById(R.id.loading_container);
+        mPreferencesContainer = (ViewGroup) super.onCreateView(
+                inflater, mPrefsView, savedInstanceState);
+        setLoading(mIsLoading, false, true /* force */);
+        mPrefsView.addView(mPreferencesContainer);
+        return rootView;
+    }
+
+    protected void setLoading(boolean loading, boolean animate) {
+        setLoading(loading, animate, false);
+    }
+
+    private void setLoading(boolean loading, boolean animate, boolean force) {
+        if (mIsLoading != loading || force) {
+            mIsLoading = loading;
+            if (getView() == null) {
+                // If there is no created view, there is no reason to animate.
+                animate = false;
+            }
+            if (mPrefsView != null) {
+                setViewShown(mPrefsView, !loading, animate);
+            }
+            if (mLoadingView != null) {
+                setViewShown(mLoadingView, loading, animate);
+            }
+        }
+    }
+
+    @Override
+    public ListView getListView() {
+        ListView listView = super.getListView();
+        if (listView.getEmptyView() == null) {
+            TextView emptyView = (TextView) getView().findViewById(R.id.no_permissions);
+            listView.setEmptyView(emptyView);
+        }
+        return listView;
+    }
+
+    private void setViewShown(final View view, boolean shown, boolean animate) {
+        if (animate) {
+            Animation animation = AnimationUtils.loadAnimation(getContext(),
+                    shown ? android.R.anim.fade_in : android.R.anim.fade_out);
+            if (shown) {
+                view.setVisibility(View.VISIBLE);
+            } else {
+                animation.setAnimationListener(new AnimationListener() {
+                    @Override
+                    public void onAnimationStart(Animation animation) {
+                    }
+
+                    @Override
+                    public void onAnimationRepeat(Animation animation) {
+                    }
+
+                    @Override
+                    public void onAnimationEnd(Animation animation) {
+                        view.setVisibility(View.INVISIBLE);
+                    }
+                });
+            }
+            view.startAnimation(animation);
+        } else {
+            view.clearAnimation();
+            view.setVisibility(shown ? View.VISIBLE : View.INVISIBLE);
+        }
+    }
+}
diff --git a/src/com/android/packageinstaller/permission/ui/SettingsWithHeader.java b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java
similarity index 97%
rename from src/com/android/packageinstaller/permission/ui/SettingsWithHeader.java
rename to src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java
index 7b58fed..acb3c61 100644
--- a/src/com/android/packageinstaller/permission/ui/SettingsWithHeader.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.handheld;
 
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
@@ -81,5 +81,4 @@
     public void onClick(View v) {
         getActivity().startActivity(mInfoIntent);
     }
-
 }
diff --git a/src/com/android/packageinstaller/permission/ui/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java
similarity index 98%
rename from src/com/android/packageinstaller/permission/ui/AllAppPermissionsFragment.java
rename to src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java
index 2fb9a51..d491012 100644
--- a/src/com/android/packageinstaller/permission/ui/AllAppPermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java
@@ -14,7 +14,7 @@
 * limitations under the License.
 */
 
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.television;
 
 import android.app.ActionBar;
 import android.app.AlertDialog;
diff --git a/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java
similarity index 98%
rename from src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java
rename to src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java
index 6396c61..42a2661 100644
--- a/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java
@@ -14,7 +14,7 @@
 * limitations under the License.
 */
 
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.television;
 
 import android.annotation.Nullable;
 import android.app.ActionBar;
@@ -50,6 +50,7 @@
 import com.android.packageinstaller.R;
 import com.android.packageinstaller.permission.model.AppPermissionGroup;
 import com.android.packageinstaller.permission.model.AppPermissions;
+import com.android.packageinstaller.permission.ui.OverlayTouchActivity;
 import com.android.packageinstaller.permission.utils.LocationUtils;
 import com.android.packageinstaller.permission.utils.SafetyNetLogger;
 import com.android.packageinstaller.permission.utils.Utils;
diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsTvViewHandler.java b/src/com/android/packageinstaller/permission/ui/television/GrantPermissionsViewHandlerImpl.java
similarity index 90%
rename from src/com/android/packageinstaller/permission/ui/GrantPermissionsTvViewHandler.java
rename to src/com/android/packageinstaller/permission/ui/television/GrantPermissionsViewHandlerImpl.java
index 0e979ab..a253882 100644
--- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsTvViewHandler.java
+++ b/src/com/android/packageinstaller/permission/ui/television/GrantPermissionsViewHandlerImpl.java
@@ -1,4 +1,4 @@
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.television;
 
 import android.content.Context;
 import android.graphics.PixelFormat;
@@ -15,11 +15,12 @@
 import android.widget.TextView;
 
 import com.android.packageinstaller.R;
+import com.android.packageinstaller.permission.ui.GrantPermissionsViewHandler;
 
 /**
  * TV-specific view handler for the grant permissions activity.
  */
-final class GrantPermissionsTvViewHandler implements GrantPermissionsViewHandler, OnClickListener {
+public final class GrantPermissionsViewHandlerImpl implements GrantPermissionsViewHandler, OnClickListener {
 
     private static final String ARG_GROUP_NAME = "ARG_GROUP_NAME";
 
@@ -37,12 +38,12 @@
     private Button mSoftDenyButton;
     private Button mHardDenyButton;
 
-    GrantPermissionsTvViewHandler(Context context) {
+    public GrantPermissionsViewHandlerImpl(Context context) {
         mContext = context;
     }
 
     @Override
-    public GrantPermissionsTvViewHandler setResultListener(ResultListener listener) {
+    public GrantPermissionsViewHandlerImpl setResultListener(ResultListener listener) {
         mResultListener = listener;
         return this;
     }
diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java
similarity index 98%
rename from src/com/android/packageinstaller/permission/ui/ManagePermissionsFragment.java
rename to src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java
index e5e06e0..47301f4 100644
--- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.television;
 
 import android.annotation.Nullable;
 import android.app.ActionBar;
@@ -202,7 +202,7 @@
             Preference extraScreenPreference = new Preference(context);
             extraScreenPreference.setKey(EXTRA_PREFS_KEY);
             extraScreenPreference.setIcon(Utils.applyTint(context,
-                    com.android.internal.R.drawable.ic_more_items,
+                    R.drawable.ic_more_items,
                     android.R.attr.colorControlNormal));
             extraScreenPreference.setTitle(R.string.additional_permissions);
             extraScreenPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
diff --git a/src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java
similarity index 98%
rename from src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java
rename to src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java
index 8dacd03..e41e05f 100644
--- a/src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.television;
 
 import android.app.ActionBar;
 import android.app.AlertDialog;
@@ -44,6 +44,7 @@
 import com.android.packageinstaller.permission.model.PermissionApps;
 import com.android.packageinstaller.permission.model.PermissionApps.Callback;
 import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp;
+import com.android.packageinstaller.permission.ui.OverlayTouchActivity;
 import com.android.packageinstaller.permission.utils.LocationUtils;
 import com.android.packageinstaller.permission.utils.SafetyNetLogger;
 import com.android.packageinstaller.permission.utils.Utils;
diff --git a/src/com/android/packageinstaller/permission/ui/PermissionsFrameFragment.java b/src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java
similarity index 90%
rename from src/com/android/packageinstaller/permission/ui/PermissionsFrameFragment.java
rename to src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java
index 40058f6..bc0e845 100644
--- a/src/com/android/packageinstaller/permission/ui/PermissionsFrameFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java
@@ -1,4 +1,20 @@
-package com.android.packageinstaller.permission.ui;
+/*
+ * 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.packageinstaller.permission.ui.television;
 
 import android.annotation.Nullable;
 import android.os.Bundle;
diff --git a/src/com/android/packageinstaller/permission/ui/SettingsWithHeader.java b/src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java
similarity index 97%
copy from src/com/android/packageinstaller/permission/ui/SettingsWithHeader.java
copy to src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java
index 7b58fed..c7f5cda 100644
--- a/src/com/android/packageinstaller/permission/ui/SettingsWithHeader.java
+++ b/src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.packageinstaller.permission.ui;
+package com.android.packageinstaller.permission.ui.television;
 
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
diff --git a/src/com/android/packageinstaller/permission/utils/LocationUtils.java b/src/com/android/packageinstaller/permission/utils/LocationUtils.java
index 512fcf4..0296ae8 100644
--- a/src/com/android/packageinstaller/permission/utils/LocationUtils.java
+++ b/src/com/android/packageinstaller/permission/utils/LocationUtils.java
@@ -36,23 +36,9 @@
 
     public static final String LOCATION_PERMISSION = Manifest.permission_group.LOCATION;
 
-    public static ArrayList<String> getLocationProviders() {
-        ArrayList<String> providers = new ArrayList<>();
-        Resources res = Resources.getSystem();
-        providers.add(res.getString(
-                com.android.internal.R.string.config_networkLocationProviderPackageName));
-
-        for (String provider :
-            res.getStringArray(com.android.internal.R.array.config_locationProviderPackageNames)) {
-            providers.add(provider);
-        }
-
-        return providers;
-    }
-
     public static void showLocationDialog(final Context context, CharSequence label) {
         new AlertDialog.Builder(context)
-                .setIcon(com.android.internal.R.drawable.ic_dialog_alert_material)
+                .setIcon(R.drawable.ic_dialog_alert_material)
                 .setTitle(android.R.string.dialog_alert_title)
                 .setMessage(context.getString(R.string.location_warning, label))
                 .setNegativeButton(R.string.ok, null)
@@ -83,5 +69,4 @@
             return false;
         }
     }
-
 }