diff options
-rw-r--r-- | AndroidManifest.xml | 2 | ||||
-rw-r--r-- | res/layout/permissions_prompt.xml | 84 | ||||
-rwxr-xr-x | res/layout/tab.xml | 6 | ||||
-rw-r--r-- | res/values/strings.xml | 7 | ||||
-rw-r--r-- | src/com/android/browser/PermissionsPrompt.java | 126 | ||||
-rw-r--r-- | src/com/android/browser/Tab.java | 33 |
6 files changed, 258 insertions, 0 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9b29fd2..6cfb028 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -46,6 +46,8 @@ <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/> <uses-permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"/> <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/> + <uses-permission android:name="android.permission.RECORD_AUDIO"/> + <uses-permission android:name="android.permission.CAMERA"/> <application android:name="Browser" android:label="@string/application_name" diff --git a/res/layout/permissions_prompt.xml b/res/layout/permissions_prompt.xml new file mode 100644 index 0000000..d18d796 --- /dev/null +++ b/res/layout/permissions_prompt.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. + + This is the layout for the Geolocation permissions prompt. +--> + +<com.android.browser.PermissionsPrompt + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@drawable/geolocation_permissions_prompt_background" + android:visibility="gone"> + + <!-- 'google.com wants to know your location' --> + <TextView android:id="@+id/message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:scrollHorizontally="true" + android:padding="6dip" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + <CheckBox android:id="@+id/remember" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@id/message" + android:layout_alignLeft="@id/message" /> + <TextView + android:paddingLeft="4dip" + android:text="@string/permissions_prompt_remember" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceSmall" + android:layout_alignBaseline="@id/remember" + android:layout_toRightOf="@id/remember" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/remember" + android:orientation="vertical" + android:divider="?android:attr/dividerHorizontal" + android:showDividers="beginning" + android:dividerPadding="16dip" + android:background="@null"> + <LinearLayout + style="?android:attr/buttonBarStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:paddingLeft="2dip" + android:paddingRight="2dip" + android:measureWithLargestChild="true" + android:background="@null"> + <Button + android:id="@+id/deny_button" + style="?android:attr/buttonBarButtonStyle" + android:layout_weight="1" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:text="@string/permissions_prompt_deny" /> + <Button + android:id="@+id/allow_button" + style="?android:attr/buttonBarButtonStyle" + android:layout_weight="1" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:text="@string/permissions_prompt_allow" /> + </LinearLayout> + </LinearLayout> + +</com.android.browser.PermissionsPrompt> diff --git a/res/layout/tab.xml b/res/layout/tab.xml index 69baf56..040c977 100755 --- a/res/layout/tab.xml +++ b/res/layout/tab.xml @@ -31,6 +31,12 @@ android:layout_height="0dip" android:layout_weight="1" /> + <!-- Permissions prompt --> + <ViewStub android:id="@+id/permissions_prompt" + android:layout="@layout/permissions_prompt" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + <!-- Geolocation permissions prompt --> <ViewStub android:id="@+id/geolocation_permissions_prompt" android:layout="@layout/geolocation_permissions_prompt" diff --git a/res/values/strings.xml b/res/values/strings.xml index 079d893..8a0fd49 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -854,6 +854,13 @@ <!-- Geolocation --> <!-- Permissions prompt --> + <string name="permissions_prompt_message"><xliff:g id="website origin" example="maps.google.com">%s</xliff:g> wants to use your <xliff:g id="resources" example="camera, microphone">%s</xliff:g>.</string> + <string name="permissions_prompt_allow">Allow</string> + <string name="permissions_prompt_deny">Deny</string> + <string name="permissions_prompt_remember">Remember preference</string> + <string name="resource_geolocation">location</string> + <string name="resource_video_capture">camera</string> + <string name="resource_audio_capture">microphone</string> <string name="geolocation_permissions_prompt_message"><xliff:g id="website origin" example="maps.google.com">%s</xliff:g> wants to know your location</string> <string name="geolocation_permissions_prompt_share">Share location</string> <string name="geolocation_permissions_prompt_dont_share">Decline</string> diff --git a/src/com/android/browser/PermissionsPrompt.java b/src/com/android/browser/PermissionsPrompt.java new file mode 100644 index 0000000..284a3ea --- /dev/null +++ b/src/com/android/browser/PermissionsPrompt.java @@ -0,0 +1,126 @@ +/* + * 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.browser; + +import android.content.Context; +import android.net.Uri; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.webkit.GeolocationPermissions; +import android.webkit.PermissionRequest; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import java.util.Enumeration; +import java.util.Vector; + +public class PermissionsPrompt extends RelativeLayout { + private TextView mMessage; + private Button mAllowButton; + private Button mDenyButton; + private CheckBox mRemember; + private PermissionRequest mRequest; + + public PermissionsPrompt(Context context) { + this(context, null); + } + + public PermissionsPrompt(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + init(); + } + + private void init() { + mMessage = (TextView) findViewById(R.id.message); + mAllowButton = (Button) findViewById(R.id.allow_button); + mDenyButton = (Button) findViewById(R.id.deny_button); + mRemember = (CheckBox) findViewById(R.id.remember); + // TODO: Retain permission. + // Hide the Remember checkBox as this feature is missing. + mRemember.setVisibility(View.INVISIBLE); + + mAllowButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + handleButtonClick(true); + } + }); + mDenyButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + handleButtonClick(false); + } + }); + } + + public void show(PermissionRequest request) { + mRequest = request; + setMessage(); + mRemember.setChecked(true); + setVisibility(View.VISIBLE); + } + + public void setMessage() { + long resources = mRequest.getResources(); + Vector<String> strings = new Vector<String>(); + if ((resources & PermissionRequest.RESOURCE_GEOLOCATION) != 0) + strings.add(getResources().getString(R.string.resource_geolocation)); + else if ((resources & PermissionRequest.RESOURCE_VIDEO_CAPTURE) != 0) + strings.add(getResources().getString(R.string.resource_video_capture)); + else if ((resources & PermissionRequest.RESOURCE_AUDIO_CAPTURE) != 0) + strings.add(getResources().getString(R.string.resource_audio_capture)); + if (strings.isEmpty()) return; + + Enumeration<String> e = strings.elements(); + StringBuilder sb = new StringBuilder(e.nextElement()); + if (e.hasMoreElements()) { + sb.append(", "); + sb.append(e.nextElement()); + } + + mMessage.setText(String.format( + getResources().getString(R.string.permissions_prompt_message), + mRequest.getOrigin(), sb.toString())); + } + + /** + * Hides the prompt. + */ + public void hide() { + setVisibility(View.GONE); + } + + /** + * Handles a click on one the buttons by invoking the callback. + */ + private void handleButtonClick(boolean allow) { + hide(); + if (allow) + mRequest.grant(mRequest.getResources()); + else + mRequest.deny(); + } +} diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java index ed20e67..668786c 100644 --- a/src/com/android/browser/Tab.java +++ b/src/com/android/browser/Tab.java @@ -50,7 +50,9 @@ import android.webkit.BrowserDownloadListener; import android.webkit.ClientCertRequest; import android.webkit.ConsoleMessage; import android.webkit.GeolocationPermissions; +import android.webkit.GeolocationPermissions.Callback; import android.webkit.HttpAuthHandler; +import android.webkit.PermissionRequest; import android.webkit.SslErrorHandler; import android.webkit.URLUtil; import android.webkit.ValueCallback; @@ -135,6 +137,8 @@ class Tab implements PictureListener { // The Geolocation permissions prompt private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt; + // The permissions prompt + private PermissionsPrompt mPermissionsPrompt; // Main WebView wrapper private View mContainer; // Main WebView @@ -912,6 +916,19 @@ class Tab implements PictureListener { } } + @Override + public void onPermissionRequest(PermissionRequest request) { + if (!mInForeground) return; + getPermissionsPrompt().show(request); + } + + @Override + public void onPermissionRequestCanceled(PermissionRequest request) { + if (mInForeground && mPermissionsPrompt != null) { + mPermissionsPrompt.hide(); + } + } + /* Adds a JavaScript error message to the system log and if the JS * console is enabled in the about:debug options, to that console * also. @@ -1232,6 +1249,10 @@ class Tab implements PictureListener { mGeolocationPermissionsPrompt.hide(); } + if (mPermissionsPrompt != null) { + mPermissionsPrompt.hide(); + } + mWebViewController.onSetWebView(this, w); if (mMainView != null) { @@ -1539,6 +1560,18 @@ class Tab implements PictureListener { } /** + * @return The permissions prompt for this tab. + */ + PermissionsPrompt getPermissionsPrompt() { + if (mPermissionsPrompt == null) { + ViewStub stub = (ViewStub) mContainer + .findViewById(R.id.permissions_prompt); + mPermissionsPrompt = (PermissionsPrompt) stub.inflate(); + } + return mPermissionsPrompt; + } + + /** * @return The application id string */ String getAppId() { |