diff options
21 files changed, 646 insertions, 1 deletions
@@ -14,7 +14,7 @@ LOCAL_STATIC_JAVA_LIBRARIES += \ android-support-v7-appcompat \ android-support-v14-preference \ android-support-v17-preference-leanback \ - android-support-v17-leanback + android-support-v17-leanback \ LOCAL_RESOURCE_DIR := \ frameworks/support/v17/leanback/res \ diff --git a/res/drawable-watch-280dpi/ic_cc_cancel.png b/res/drawable-watch-280dpi/ic_cc_cancel.png Binary files differnew file mode 100644 index 00000000..249b8697 --- /dev/null +++ b/res/drawable-watch-280dpi/ic_cc_cancel.png diff --git a/res/drawable-watch-280dpi/ic_cc_checkmark.png b/res/drawable-watch-280dpi/ic_cc_checkmark.png Binary files differnew file mode 100644 index 00000000..94db9ab0 --- /dev/null +++ b/res/drawable-watch-280dpi/ic_cc_checkmark.png diff --git a/res/drawable-watch-hdpi/ic_cc_cancel.png b/res/drawable-watch-hdpi/ic_cc_cancel.png Binary files differnew file mode 100644 index 00000000..a57893e1 --- /dev/null +++ b/res/drawable-watch-hdpi/ic_cc_cancel.png diff --git a/res/drawable-watch-hdpi/ic_cc_checkmark.png b/res/drawable-watch-hdpi/ic_cc_checkmark.png Binary files differnew file mode 100644 index 00000000..29f9ecd9 --- /dev/null +++ b/res/drawable-watch-hdpi/ic_cc_checkmark.png diff --git a/res/drawable-watch-mdpi/ic_cc_cancel.png b/res/drawable-watch-mdpi/ic_cc_cancel.png Binary files differnew file mode 100644 index 00000000..87fc65ab --- /dev/null +++ b/res/drawable-watch-mdpi/ic_cc_cancel.png diff --git a/res/drawable-watch-mdpi/ic_cc_checkmark.png b/res/drawable-watch-mdpi/ic_cc_checkmark.png Binary files differnew file mode 100644 index 00000000..0989daa6 --- /dev/null +++ b/res/drawable-watch-mdpi/ic_cc_checkmark.png diff --git a/res/drawable-watch-xhdpi/ic_cc_cancel.png b/res/drawable-watch-xhdpi/ic_cc_cancel.png Binary files differnew file mode 100644 index 00000000..fec6ecb8 --- /dev/null +++ b/res/drawable-watch-xhdpi/ic_cc_cancel.png diff --git a/res/drawable-watch-xhdpi/ic_cc_checkmark.png b/res/drawable-watch-xhdpi/ic_cc_checkmark.png Binary files differnew file mode 100644 index 00000000..f98cc1ec --- /dev/null +++ b/res/drawable-watch-xhdpi/ic_cc_checkmark.png diff --git a/res/drawable-watch/action_negative_bg.xml b/res/drawable-watch/action_negative_bg.xml new file mode 100644 index 00000000..f1c33b54 --- /dev/null +++ b/res/drawable-watch/action_negative_bg.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="false"> + <shape android:shape="oval"> + <solid android:color="@color/circular_button_disabled"/> + <size android:width="40dp" android:height="40dp" /> + </shape> + </item> + <item android:state_pressed="true"> + <shape android:shape="oval"> + <solid android:color="#757575"/> + <size android:width="40dp" android:height="40dp" /> + </shape> + </item> + <item> + <shape android:shape="oval"> + <solid android:color="#BDBDBD"/> + <size android:width="40dp" android:height="40dp" /> + </shape> + </item> +</selector> diff --git a/res/drawable-watch/action_positive_bg.xml b/res/drawable-watch/action_positive_bg.xml new file mode 100644 index 00000000..bc3e88ba --- /dev/null +++ b/res/drawable-watch/action_positive_bg.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="false"> + <shape android:shape="oval"> + <solid android:color="@color/circular_button_disabled"/> + <size android:width="40dp" android:height="40dp" /> + </shape> + </item> + <item android:state_pressed="true"> + <shape android:shape="oval"> + <solid android:color="#009688"/> + <size android:width="40dp" android:height="40dp" /> + </shape> + </item> + <item> + <shape android:shape="oval"> + <solid android:color="#00BFA5"/> + <size android:width="40dp" android:height="40dp" /> + </shape> + </item> +</selector> diff --git a/res/drawable-watch/cancel_button.xml b/res/drawable-watch/cancel_button.xml new file mode 100644 index 00000000..5b16f549 --- /dev/null +++ b/res/drawable-watch/cancel_button.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > + <item android:drawable="@drawable/action_negative_bg" /> + <item> + <bitmap android:src="@drawable/ic_cc_cancel" android:gravity="center" /> + </item> +</layer-list> diff --git a/res/drawable-watch/confirm_button.xml b/res/drawable-watch/confirm_button.xml new file mode 100644 index 00000000..6a895ec6 --- /dev/null +++ b/res/drawable-watch/confirm_button.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > + <item android:drawable="@drawable/action_positive_bg" /> + <item> + <bitmap android:src="@drawable/ic_cc_checkmark" android:gravity="center" /> + </item> +</layer-list> diff --git a/res/layout-watch/grant_permissions.xml b/res/layout-watch/grant_permissions.xml new file mode 100644 index 00000000..2d567068 --- /dev/null +++ b/res/layout-watch/grant_permissions.xml @@ -0,0 +1,121 @@ +<?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. +--> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/confirmation" + android:layout_width="match_parent" + android:layout_height="match_parent" + > + + <ScrollView + android:id="@+id/scrolling_container" + android:overScrollMode="never" + android:scrollbars="none" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <LinearLayout + android:id="@+id/content" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/current_page_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_marginBottom="@dimen/grant_permissions_app_breadcrumb_margin_bottom" + android:textAppearance="@style/GrantPermissions.BreadcrumbText" /> + + <ImageView + android:id="@+id/icon" + android:layout_width="@dimen/grant_permissions_app_icon_size" + android:layout_height="@dimen/grant_permissions_app_icon_size" + android:tint="@color/grant_permissions_app_color" + android:layout_gravity="center" + android:layout_marginTop="@dimen/grant_permissions_app_icon_margin_top"/> + + <TextView + android:id="@+id/message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:textSize="20sp" + android:gravity="center" + android:fontFamily="sans-serif-condensed-light" + android:textAppearance="@style/GrantPermissions.TitleText"/> + + <!-- TODO: Change this to use a ViewStub instead of show/hiding the two layouts --> + <FrameLayout android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/button_bar_container" + android:layout_gravity="bottom" + android:background="#FF606060"> + <FrameLayout + android:id="@+id/horizontal_button_bar" + android:layout_width="match_parent" + android:layout_height="72dp"> + <Button + android:id="@+id/horizontal_deny_button" + android:layout_width="54dp" + android:layout_height="54dp" + android:layout_gravity="top|left" + android:layout_marginLeft="16dp" + android:layout_marginTop="9dp" + android:background="@drawable/cancel_button"/> + + <Button + android:id="@+id/horizontal_allow_button" + android:layout_width="54dp" + android:layout_height="54dp" + android:layout_gravity="top|right" + android:layout_marginRight="16dp" + android:layout_marginTop="9dp" + android:background="@drawable/confirm_button"/> + </FrameLayout> + + <FrameLayout + android:id="@+id/vertical_button_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone"> + <LinearLayout + android:id="@+id/buttonPanel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + <Button + android:id="@+id/vertical_allow_button" + style="@style/Widget.WearDiag.Button"/> + + <Button + android:id="@+id/vertical_deny_button" + style="@style/Widget.WearDiag.Button"/> + + <Button + android:id="@+id/vertical_deny_do_not_ask_again_button" + style="@style/Widget.WearDiag.Button"/> + </LinearLayout> + </FrameLayout> + </FrameLayout> + </LinearLayout> + </ScrollView> +</FrameLayout>
\ No newline at end of file diff --git a/res/values-watch/colors.xml b/res/values-watch/colors.xml new file mode 100644 index 00000000..903bfef5 --- /dev/null +++ b/res/values-watch/colors.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. +--> + +<resources> + <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> + <color name="grant_permissions_title_color">@color/grant_permissions_white_text_alpha_70</color> + + <color name="grant_permissions_white_text_alpha_100">@color/off_white</color> + <color name="grant_permissions_white_text_alpha_70">#b2eeeeee</color> + + <color name="off_white">#ffeeeeee</color> + + <!-- Copied from wearable support --> + <color name="circular_button_disabled">#757575</color> +</resources> diff --git a/res/values-watch/dimens.xml b/res/values-watch/dimens.xml new file mode 100644 index 00000000..29a65fdc --- /dev/null +++ b/res/values-watch/dimens.xml @@ -0,0 +1,28 @@ +<?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> + <dimen name="grant_permissions_app_icon_size">32dp</dimen> + <dimen name="grant_permissions_app_icon_margin_top">8dp</dimen> + + <dimen name="grant_permissions_app_breadcrumb_margin_bottom">3dp</dimen> + + <dimen name="action_dialog_z">16dp</dimen> + + <!-- Confirmation Dialog --> + <dimen name="conf_diag_floating_height">16dp</dimen> + +</resources> diff --git a/res/values-watch/strings.xml b/res/values-watch/strings.xml new file mode 100644 index 00000000..161ff834 --- /dev/null +++ b/res/values-watch/strings.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. +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Title for the dialog button to deny a permission grant and never ask the user again. --> + <string name="grant_dialog_button_deny_dont_ask_again">Deny and don\'t ask again</string> + + <!-- Template for the current permission from the total number of permissions. --> + <string name="current_permission_template"> + <xliff:g id="current_permission_index" example="1">%1$s</xliff:g> / + <xliff:g id="permission_count" example="2">%2$s</xliff:g> + </string> + + <!-- Preference row title for showing system apps. --> + <string name="preference_show_system_apps">Show system apps</string> +</resources> diff --git a/res/values-watch/themes.xml b/res/values-watch/themes.xml new file mode 100644 index 00000000..7a27bf7c --- /dev/null +++ b/res/values-watch/themes.xml @@ -0,0 +1,67 @@ +<?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="Settings" parent="Theme.Leanback"> + <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Permissions</item> + </style> + + <style name="GrantPermissions" parent="Theme.Leanback"> + <item name="android:windowIsFloating">true</item> + <item name="android:windowAnimationStyle">@style/Animation.Snackbar</item> + <item name="android:windowElevation">@dimen/action_dialog_z</item> + </style> + + <style name="GrantPermissions.BreadcrumbText"> + <item name="android:fontFamily">sans-serif-condensed</item> + <item name="android:textSize">14sp</item> + <item name="android:textColor">@color/grant_permissions_progress_color</item> + </style> + + <style name="GrantPermissions.TitleText"> + <item name="android:fontFamily">sans-serif-light</item> + <item name="android:textSize">18sp</item> + <item name="android:textColor">@color/grant_permissions_title_color</item> + <item name="android:lineSpacingMultiplier">1.221</item> + </style> + + <style name="Animation.Snackbar" parent="@android:style/Animation"> + <item name="android:windowEnterAnimation">@anim/snackbar_enter</item> + <item name="android:windowExitAnimation">@anim/snackbar_exit</item> + </style> + + <!-- Copied from WearableSupport lib --> + <style name="TextAppearance.WearDiag" parent="android:TextAppearance.Medium"> + <item name="android:textColor">#FFFFFF</item> + <item name="android:textSize">16sp</item> + </style> + <style name="TextAppearance.WearDiag.Button"> + <item name="android:textSize">16sp</item> + </style> + <style name="Widget.WearDiag.Button" parent="@android:style/Widget.DeviceDefault.Button"> + <item name="android:fontFamily">sans-serif-condensed-light</item> + <item name="android:gravity">center_vertical|left</item> + <item name="android:textAppearance">@style/TextAppearance.WearDiag.Button</item> + <item name="android:background">@android:color/transparent</item> + <item name="android:minLines">1</item> + <item name="android:maxLines">3</item> + <item name="android:ellipsize">marquee</item> + <item name="android:layout_height">60dp</item> + <item name="android:layout_width">match_parent</item> + <item name="android:drawablePadding">12dp</item> + </style> +</resources> diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java index 0c087350..c1597f16 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java @@ -73,6 +73,8 @@ public class GrantPermissionsActivity extends OverlayTouchActivity if (Utils.isTelevision(this)) { mViewHandler = new GrantPermissionsTvViewHandler(this).setResultListener(this); + } else if (isWatch()) { + mViewHandler = new GrantPermissionsWatchViewHandler(this).setResultListener(this); } else { mViewHandler = new GrantPermissionsDefaultViewHandler(this).setResultListener(this); } @@ -368,6 +370,11 @@ public class GrantPermissionsActivity extends OverlayTouchActivity SafetyNetLogger.logPermissionsRequested(mAppPermissions.getPackageInfo(), groups); } + private boolean isWatch() { + PackageManager pm = getPackageManager(); + return pm.hasSystemFeature(pm.FEATURE_WATCH); + } + private static final class GroupState { static final int STATE_UNKNOWN = 0; static final int STATE_ALLOWED = 1; diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsWatchViewHandler.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsWatchViewHandler.java new file mode 100644 index 00000000..ac573c43 --- /dev/null +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsWatchViewHandler.java @@ -0,0 +1,159 @@ +package com.android.packageinstaller.permission.ui; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.graphics.drawable.Icon; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.view.WindowManager; + +import com.android.packageinstaller.R; + +/** + * Watch-specific view handler for the grant permissions activity. + */ +final class GrantPermissionsWatchViewHandler extends PermissionConfirmationViewHandler + implements GrantPermissionsViewHandler { + private static final String TAG = "GrantPermissionsViewH"; + + private static final String ARG_GROUP_NAME = "ARG_GROUP_NAME"; + + private final Context mContext; + + private ResultListener mResultListener; + + private String mGroupName; + private boolean mShowDoNotAsk; + + private CharSequence mMessage; + private String mCurrentPageText; + private Icon mIcon; + + GrantPermissionsWatchViewHandler(Context context) { + super(context); + mContext = context; + } + + @Override + public GrantPermissionsWatchViewHandler setResultListener(ResultListener listener) { + mResultListener = listener; + return this; + } + + @Override + public View createView() { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "createView()"); + } + + mShowDoNotAsk = false; + + return super.createView(); + } + + @Override + public void updateWindowAttributes(WindowManager.LayoutParams outLayoutParams) { + outLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; + outLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; + outLayoutParams.format = PixelFormat.OPAQUE; + outLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG; + outLayoutParams.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; + } + + @Override + public void updateUi(String groupName, int groupCount, int groupIndex, Icon icon, + CharSequence message, boolean showDoNotAsk) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "updateUi() - groupName: " + groupName + + ", groupCount: " + groupCount + + ", groupIndex: " + groupIndex + + ", icon: " + icon + + ", message: " + message + + ", showDoNotAsk: " + showDoNotAsk); + } + + mGroupName = groupName; + mShowDoNotAsk = showDoNotAsk; + mMessage = message; + mIcon = icon; + mCurrentPageText = (groupCount > 1 ? + mContext.getString(R.string.current_permission_template, groupIndex + 1, groupCount) + : null); + + invalidate(); + } + + @Override + public void saveInstanceState(Bundle outState) { + outState.putString(ARG_GROUP_NAME, mGroupName); + } + + @Override + public void loadInstanceState(Bundle savedInstanceState) { + mGroupName = savedInstanceState.getString(ARG_GROUP_NAME); + } + + @Override + public void onBackPressed() { + if (mResultListener != null) { + mResultListener.onPermissionGrantResult(mGroupName, false, false); + } + } + + @Override // PermissionConfirmationViewHandler + public void onAllow() { + onClick(true /* granted */, false /* doNotAskAgain */); + } + + @Override // PermissionConfirmationViewHandler + public void onDeny() { + onClick(false /* granted */, false /* doNotAskAgain */); + } + + @Override // PermissionConfirmationViewHandler + public void onDenyDoNotAskAgain() { + onClick(false /* granted */, true /* doNotAskAgain */); + } + + @Override // PermissionConfirmationViewHandler + public CharSequence getCurrentPageText() { + return mCurrentPageText; + } + + @Override // PermissionConfirmationViewHandler + public Icon getPermissionIcon() { + return mIcon; + } + + @Override // PermissionConfirmationViewHandler + public CharSequence getMessage() { + return mMessage; + } + + @Override // PermissionConfirmationViewHandler + public int getButtonBarMode() { + return mShowDoNotAsk ? MODE_VERTICAL_BUTTONS : MODE_HORIZONTAL_BUTTONS; + } + + @Override // PermissionConfirmationViewHandler + public CharSequence getVerticalAllowText() { + return mContext.getString(R.string.grant_dialog_button_allow); + } + + @Override // PermissionConfirmationViewHandler + public CharSequence getVerticalDenyText() { + return mContext.getString(R.string.grant_dialog_button_deny); + } + + @Override // PermissionConfirmationViewHandler + public CharSequence getVerticalDenyDoNotAskAgainText() { + return mContext.getString(R.string.grant_dialog_button_deny_dont_ask_again); + } + + private void onClick(boolean granted, boolean doNotAskAgain) { + if (mResultListener != null) { + mResultListener.onPermissionGrantResult(mGroupName, granted, doNotAskAgain); + } + } +} diff --git a/src/com/android/packageinstaller/permission/ui/PermissionConfirmationViewHandler.java b/src/com/android/packageinstaller/permission/ui/PermissionConfirmationViewHandler.java new file mode 100644 index 00000000..63ed0a45 --- /dev/null +++ b/src/com/android/packageinstaller/permission/ui/PermissionConfirmationViewHandler.java @@ -0,0 +1,149 @@ +package com.android.packageinstaller.permission.ui; + +import android.content.Context; +import android.graphics.drawable.Icon; +import android.os.Handler; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.ScrollView; +import android.widget.TextView; + +import com.android.packageinstaller.R; + +public abstract class PermissionConfirmationViewHandler implements + View.OnClickListener { + public static final int MODE_HORIZONTAL_BUTTONS = 0; + public static final int MODE_VERTICAL_BUTTONS = 1; + + private View mRoot; + private TextView mCurrentPageText; + private ImageView mIcon; + private TextView mMessage; + private ScrollView mScrollingContainer; + private ViewGroup mContent; + private ViewGroup mHorizontalButtonBar; + private ViewGroup mVerticalButtonBar; + private Button mVerticalAllow; + private Button mVerticalDeny; + private Button mVerticalDenyDoNotAskAgain; + private View mButtonBarContainer; + + private Context mContext; + + // TODO: Move these into a builder + public abstract void onAllow(); + public abstract void onDeny(); + public abstract void onDenyDoNotAskAgain(); + public abstract CharSequence getVerticalAllowText(); + public abstract CharSequence getVerticalDenyText(); + public abstract CharSequence getVerticalDenyDoNotAskAgainText(); + public abstract CharSequence getCurrentPageText(); + public abstract Icon getPermissionIcon(); + public abstract CharSequence getMessage(); + + public PermissionConfirmationViewHandler(Context context) { + mContext = context; + } + + public View createView() { + mRoot = LayoutInflater.from(mContext).inflate(R.layout.grant_permissions, null); + + mMessage = (TextView) mRoot.findViewById(R.id.message); + mCurrentPageText = (TextView) mRoot.findViewById(R.id.current_page_text); + mIcon = (ImageView) mRoot.findViewById(R.id.icon); + mButtonBarContainer = mRoot.findViewById(R.id.button_bar_container); + mContent = (ViewGroup) mRoot.findViewById(R.id.content); + mScrollingContainer = (ScrollView) mRoot.findViewById(R.id.scrolling_container); + mHorizontalButtonBar = (ViewGroup) mRoot.findViewById(R.id.horizontal_button_bar); + mVerticalButtonBar = (ViewGroup) mRoot.findViewById(R.id.vertical_button_bar); + + Button horizontalAllow = (Button) mRoot.findViewById(R.id.horizontal_allow_button); + Button horizontalDeny = (Button) mRoot.findViewById(R.id.horizontal_deny_button); + horizontalAllow.setOnClickListener(this); + horizontalDeny.setOnClickListener(this); + + mVerticalAllow = (Button) mRoot.findViewById(R.id.vertical_allow_button); + mVerticalDeny = (Button) mRoot.findViewById(R.id.vertical_deny_button); + mVerticalDenyDoNotAskAgain = + (Button) mRoot.findViewById(R.id.vertical_deny_do_not_ask_again_button); + mVerticalAllow.setOnClickListener(this); + mVerticalDeny.setOnClickListener(this); + mVerticalDenyDoNotAskAgain.setOnClickListener(this); + + return mRoot; + } + + /** + * Child class should override this for other modes. Call invalidate() to update the UI to the + * new button mode. + * @return The current mode the layout should use for the buttons + */ + public int getButtonBarMode() { + return MODE_HORIZONTAL_BUTTONS; + } + + public void invalidate() { + CharSequence currentPageText = getCurrentPageText(); + if (!TextUtils.isEmpty(currentPageText)) { + mCurrentPageText.setText(currentPageText); + mCurrentPageText.setVisibility(View.VISIBLE); + } else { + mCurrentPageText.setVisibility(View.INVISIBLE); + } + + Icon icon = getPermissionIcon(); + if (icon != null) { + mIcon.setImageIcon(icon); + mIcon.setVisibility(View.VISIBLE); + } else { + mIcon.setVisibility(View.INVISIBLE); + } + + mMessage.setText(getMessage()); + + switch (getButtonBarMode()) { + case MODE_HORIZONTAL_BUTTONS: + mHorizontalButtonBar.setVisibility(View.VISIBLE); + mVerticalButtonBar.setVisibility(View.GONE); + break; + case MODE_VERTICAL_BUTTONS: + mHorizontalButtonBar.setVisibility(View.GONE); + mVerticalButtonBar.setVisibility(View.VISIBLE); + mVerticalAllow.setText(getVerticalAllowText()); + mVerticalDeny.setText(getVerticalDenyText()); + mVerticalDenyDoNotAskAgain.setText(getVerticalDenyDoNotAskAgainText()); + + mVerticalAllow.setCompoundDrawablesWithIntrinsicBounds( + mContext.getDrawable(R.drawable.confirm_button), null, null, null); + mVerticalDeny.setCompoundDrawablesWithIntrinsicBounds( + mContext.getDrawable(R.drawable.cancel_button), null, null, null); + mVerticalDenyDoNotAskAgain.setCompoundDrawablesWithIntrinsicBounds( + mContext.getDrawable(R.drawable.cancel_button), null, null, null); + break; + } + + mScrollingContainer.scrollTo(0, 0); + } + + @Override + public void onClick(View v) { + int id = v.getId(); + switch (id) { + case R.id.horizontal_allow_button: + case R.id.vertical_allow_button: + onAllow(); + break; + case R.id.horizontal_deny_button: + case R.id.vertical_deny_button: + onDeny(); + break; + case R.id.vertical_deny_do_not_ask_again_button: + onDenyDoNotAskAgain(); + break; + } + } +} |