Replaced video calling/camera permission dialog with a toast.
Since we are given the camera permission by default for video calling, we don't
need to request it from the framework. But, for privacy reasons, we still need
to tell the user that we have it.
Since we're changing the preference for call composer, v10.1 users will see this
this toast again if they've never made a video call.
The toast is shown in the following situations:
1. If a user receives a video call
2. If a user makes a video call
3. If the user opens call composer
The toast doesn't show:
1. If the user has already seen the toast anywhere before
2. If the user has revoked the system permission and grants it
with a system dialog
Bug: 36608790,63405063
Test: manual
PiperOrigin-RevId: 162258610
Change-Id: Ie93413c9c2e1f083919e7183eb920100b06fd4a4
diff --git a/java/com/android/incallui/CallButtonPresenter.java b/java/com/android/incallui/CallButtonPresenter.java
index dbb6a1c..d4b77ad 100644
--- a/java/com/android/incallui/CallButtonPresenter.java
+++ b/java/com/android/incallui/CallButtonPresenter.java
@@ -414,7 +414,7 @@
final boolean showMute = call.can(android.telecom.Call.Details.CAPABILITY_MUTE);
final boolean hasCameraPermission =
- isVideo && VideoUtils.hasCameraPermissionAndAllowedByUser(mContext);
+ isVideo && VideoUtils.hasCameraPermissionAndShownPrivacyToast(mContext);
// Disabling local video doesn't seem to work when dialing. See b/30256571.
final boolean showPauseVideo =
isVideo
diff --git a/java/com/android/incallui/VideoCallPresenter.java b/java/com/android/incallui/VideoCallPresenter.java
index 70f95e0..233b2b5 100644
--- a/java/com/android/incallui/VideoCallPresenter.java
+++ b/java/com/android/incallui/VideoCallPresenter.java
@@ -30,6 +30,7 @@
import com.android.dialer.common.LogUtil;
import com.android.dialer.compat.CompatUtils;
import com.android.dialer.configprovider.ConfigProviderBindings;
+import com.android.dialer.util.PermissionsUtil;
import com.android.incallui.InCallPresenter.InCallDetailsListener;
import com.android.incallui.InCallPresenter.InCallOrientationListener;
import com.android.incallui.InCallPresenter.InCallStateListener;
@@ -186,7 +187,7 @@
*/
public static boolean showOutgoingVideo(
Context context, int videoState, int sessionModificationState) {
- if (!VideoUtils.hasCameraPermissionAndAllowedByUser(context)) {
+ if (!VideoUtils.hasCameraPermissionAndShownPrivacyToast(context)) {
LogUtil.i("VideoCallPresenter.showOutgoingVideo", "Camera permission is disabled by user.");
return false;
}
@@ -421,7 +422,7 @@
@Override
public void onCameraPermissionGranted() {
LogUtil.i("VideoCallPresenter.onCameraPermissionGranted", "");
- VideoUtils.setCameraAllowedByUser(mContext);
+ PermissionsUtil.setCameraPrivacyToastShown(mContext);
enableCamera(mPrimaryCall.getVideoCall(), isCameraRequired());
showVideoUi(
mPrimaryCall.getVideoState(),
@@ -839,7 +840,7 @@
return;
}
- boolean hasCameraPermission = VideoUtils.hasCameraPermissionAndAllowedByUser(mContext);
+ boolean hasCameraPermission = VideoUtils.hasCameraPermissionAndShownPrivacyToast(mContext);
if (!hasCameraPermission) {
videoCall.setCamera(null);
mPreviewSurfaceState = PreviewSurfaceState.NONE;
@@ -1081,22 +1082,23 @@
}
@Override
- public boolean shouldShowCameraPermissionDialog() {
+ public boolean shouldShowCameraPermissionToast() {
if (mPrimaryCall == null) {
- LogUtil.i("VideoCallPresenter.shouldShowCameraPermissionDialog", "null call");
+ LogUtil.i("VideoCallPresenter.shouldShowCameraPermissionToast", "null call");
return false;
}
if (mPrimaryCall.didShowCameraPermission()) {
LogUtil.i(
- "VideoCallPresenter.shouldShowCameraPermissionDialog", "already shown for this call");
+ "VideoCallPresenter.shouldShowCameraPermissionToast", "already shown for this call");
return false;
}
if (!ConfigProviderBindings.get(mContext)
.getBoolean("camera_permission_dialog_allowed", true)) {
- LogUtil.i("VideoCallPresenter.shouldShowCameraPermissionDialog", "disabled by config");
+ LogUtil.i("VideoCallPresenter.shouldShowCameraPermissionToast", "disabled by config");
return false;
}
- return !VideoUtils.hasCameraPermission(mContext) || !VideoUtils.isCameraAllowedByUser(mContext);
+ return !VideoUtils.hasCameraPermission(mContext)
+ || !PermissionsUtil.hasCameraPrivacyToastShown(mContext);
}
@Override
diff --git a/java/com/android/incallui/answer/impl/AnswerFragment.java b/java/com/android/incallui/answer/impl/AnswerFragment.java
index 4431053..b5dd117 100644
--- a/java/com/android/incallui/answer/impl/AnswerFragment.java
+++ b/java/com/android/incallui/answer/impl/AnswerFragment.java
@@ -718,7 +718,7 @@
}
view.setSystemUiVisibility(flags);
if (isVideoCall() || isVideoUpgradeRequest()) {
- if (VideoUtils.hasCameraPermissionAndAllowedByUser(getContext())) {
+ if (VideoUtils.hasCameraPermissionAndShownPrivacyToast(getContext())) {
if (isSelfManagedCamera()) {
answerVideoCallScreen = new SelfManagedAnswerVideoCallScreen(getCallId(), this, view);
} else {
diff --git a/java/com/android/incallui/video/impl/CameraPermissionDialogFragment.java b/java/com/android/incallui/video/impl/CameraPermissionDialogFragment.java
deleted file mode 100644
index 9e5ab3c..0000000
--- a/java/com/android/incallui/video/impl/CameraPermissionDialogFragment.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 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.incallui.video.impl;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import com.android.dialer.common.FragmentUtils;
-
-/** Dialog fragment to ask for camera permission from user. */
-public class CameraPermissionDialogFragment extends DialogFragment {
-
- static CameraPermissionDialogFragment newInstance() {
- CameraPermissionDialogFragment fragment = new CameraPermissionDialogFragment();
- return fragment;
- }
-
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle bundle) {
- return new AlertDialog.Builder(getContext())
- .setTitle(R.string.camera_permission_dialog_title)
- .setMessage(R.string.camera_permission_dialog_message)
- .setPositiveButton(
- R.string.camera_permission_dialog_positive_button,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- CameraPermissionDialogCallback fragment =
- FragmentUtils.getParentUnsafe(
- CameraPermissionDialogFragment.this, CameraPermissionDialogCallback.class);
- fragment.onCameraPermissionGranted();
- }
- })
- .setNegativeButton(
- R.string.camera_permission_dialog_negative_button,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- })
- .create();
- }
-
- /** Callback for being granted camera permission. */
- public interface CameraPermissionDialogCallback {
- void onCameraPermissionGranted();
- }
-}
diff --git a/java/com/android/incallui/video/impl/SurfaceViewVideoCallFragment.java b/java/com/android/incallui/video/impl/SurfaceViewVideoCallFragment.java
index 489f72b..95bdd6b 100644
--- a/java/com/android/incallui/video/impl/SurfaceViewVideoCallFragment.java
+++ b/java/com/android/incallui/video/impl/SurfaceViewVideoCallFragment.java
@@ -50,6 +50,7 @@
import com.android.dialer.common.FragmentUtils;
import com.android.dialer.common.LogUtil;
import com.android.dialer.compat.ActivityCompat;
+import com.android.dialer.util.PermissionsUtil;
import com.android.incallui.audioroute.AudioRouteSelectorDialogFragment;
import com.android.incallui.audioroute.AudioRouteSelectorDialogFragment.AudioRouteSelectorPresenter;
import com.android.incallui.contactgrid.ContactGridManager;
@@ -65,7 +66,6 @@
import com.android.incallui.incall.protocol.PrimaryCallState;
import com.android.incallui.incall.protocol.PrimaryInfo;
import com.android.incallui.incall.protocol.SecondaryInfo;
-import com.android.incallui.video.impl.CameraPermissionDialogFragment.CameraPermissionDialogCallback;
import com.android.incallui.video.impl.CheckableImageButton.OnCheckedChangeListener;
import com.android.incallui.video.protocol.VideoCallScreen;
import com.android.incallui.video.protocol.VideoCallScreenDelegate;
@@ -85,15 +85,12 @@
OnClickListener,
OnCheckedChangeListener,
AudioRouteSelectorPresenter,
- OnSystemUiVisibilityChangeListener,
- CameraPermissionDialogCallback {
+ OnSystemUiVisibilityChangeListener {
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
static final String ARG_CALL_ID = "call_id";
private static final int CAMERA_PERMISSION_REQUEST_CODE = 1;
- private static final String CAMERA_PERMISSION_DIALOG_FRAMENT_TAG =
- "CameraPermissionDialogFragment";
private static final long CAMERA_PERMISSION_DIALOG_DELAY_IN_MILLIS = 2000L;
private static final long VIDEO_OFF_VIEW_FADE_OUT_DELAY_IN_MILLIS = 2000L;
@@ -131,7 +128,7 @@
new Runnable() {
@Override
public void run() {
- if (videoCallScreenDelegate.shouldShowCameraPermissionDialog()) {
+ if (videoCallScreenDelegate.shouldShowCameraPermissionToast()) {
LogUtil.i(
"SurfaceViewVideoCallFragment.cameraPermissionDialogRunnable", "showing dialog");
checkCameraPermission();
@@ -612,7 +609,7 @@
@Override
public void onCheckedChanged(CheckableImageButton button, boolean isChecked) {
if (button == cameraOffButton) {
- if (!isChecked && !VideoUtils.hasCameraPermissionAndAllowedByUser(getContext())) {
+ if (!isChecked && !VideoUtils.hasCameraPermissionAndShownPrivacyToast(getContext())) {
LogUtil.i("SurfaceViewVideoCallFragment.onCheckedChanged", "show camera permission dialog");
checkCameraPermission();
} else {
@@ -1048,24 +1045,19 @@
}
}
- @Override
- public void onCameraPermissionGranted() {
- videoCallScreenDelegate.onCameraPermissionGranted();
- }
-
private void checkCameraPermission() {
// Checks if user has consent of camera permission and the permission is granted.
// If camera permission is revoked, shows system permission dialog.
// If camera permission is granted but user doesn't have consent of camera permission
// (which means it's first time making video call), shows custom dialog instead. This
// will only be shown to user once.
- if (!VideoUtils.hasCameraPermissionAndAllowedByUser(getContext())) {
+ if (!VideoUtils.hasCameraPermissionAndShownPrivacyToast(getContext())) {
videoCallScreenDelegate.onCameraPermissionDialogShown();
if (!VideoUtils.hasCameraPermission(getContext())) {
requestPermissions(new String[] {permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
} else {
- CameraPermissionDialogFragment.newInstance()
- .show(getChildFragmentManager(), CAMERA_PERMISSION_DIALOG_FRAMENT_TAG);
+ PermissionsUtil.showCameraPermissionToast(getContext());
+ videoCallScreenDelegate.onCameraPermissionGranted();
}
}
}
diff --git a/java/com/android/incallui/video/impl/VideoCallFragment.java b/java/com/android/incallui/video/impl/VideoCallFragment.java
index 4d17223..84e01bd 100644
--- a/java/com/android/incallui/video/impl/VideoCallFragment.java
+++ b/java/com/android/incallui/video/impl/VideoCallFragment.java
@@ -61,6 +61,7 @@
import com.android.dialer.common.FragmentUtils;
import com.android.dialer.common.LogUtil;
import com.android.dialer.compat.ActivityCompat;
+import com.android.dialer.util.PermissionsUtil;
import com.android.incallui.audioroute.AudioRouteSelectorDialogFragment;
import com.android.incallui.audioroute.AudioRouteSelectorDialogFragment.AudioRouteSelectorPresenter;
import com.android.incallui.contactgrid.ContactGridManager;
@@ -76,7 +77,6 @@
import com.android.incallui.incall.protocol.PrimaryCallState;
import com.android.incallui.incall.protocol.PrimaryInfo;
import com.android.incallui.incall.protocol.SecondaryInfo;
-import com.android.incallui.video.impl.CameraPermissionDialogFragment.CameraPermissionDialogCallback;
import com.android.incallui.video.impl.CheckableImageButton.OnCheckedChangeListener;
import com.android.incallui.video.protocol.VideoCallScreen;
import com.android.incallui.video.protocol.VideoCallScreenDelegate;
@@ -94,8 +94,7 @@
OnClickListener,
OnCheckedChangeListener,
AudioRouteSelectorPresenter,
- OnSystemUiVisibilityChangeListener,
- CameraPermissionDialogCallback {
+ OnSystemUiVisibilityChangeListener {
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
static final String ARG_CALL_ID = "call_id";
@@ -107,8 +106,6 @@
private static final float ASPECT_RATIO_MATCH_THRESHOLD = 0.2f;
private static final int CAMERA_PERMISSION_REQUEST_CODE = 1;
- private static final String CAMERA_PERMISSION_DIALOG_FRAMENT_TAG =
- "CameraPermissionDialogFragment";
private static final long CAMERA_PERMISSION_DIALOG_DELAY_IN_MILLIS = 2000L;
private static final long VIDEO_OFF_VIEW_FADE_OUT_DELAY_IN_MILLIS = 2000L;
@@ -158,7 +155,7 @@
new Runnable() {
@Override
public void run() {
- if (videoCallScreenDelegate.shouldShowCameraPermissionDialog()) {
+ if (videoCallScreenDelegate.shouldShowCameraPermissionToast()) {
LogUtil.i("VideoCallFragment.cameraPermissionDialogRunnable", "showing dialog");
checkCameraPermission();
}
@@ -653,7 +650,7 @@
@Override
public void onCheckedChanged(CheckableImageButton button, boolean isChecked) {
if (button == cameraOffButton) {
- if (!isChecked && !VideoUtils.hasCameraPermissionAndAllowedByUser(getContext())) {
+ if (!isChecked && !VideoUtils.hasCameraPermissionAndShownPrivacyToast(getContext())) {
LogUtil.i("VideoCallFragment.onCheckedChanged", "show camera permission dialog");
checkCameraPermission();
} else {
@@ -1256,24 +1253,19 @@
videoCallScreenDelegate.onSystemUiVisibilityChange(navBarVisible);
}
- @Override
- public void onCameraPermissionGranted() {
- videoCallScreenDelegate.onCameraPermissionGranted();
- }
-
private void checkCameraPermission() {
// Checks if user has consent of camera permission and the permission is granted.
// If camera permission is revoked, shows system permission dialog.
// If camera permission is granted but user doesn't have consent of camera permission
// (which means it's first time making video call), shows custom dialog instead. This
// will only be shown to user once.
- if (!VideoUtils.hasCameraPermissionAndAllowedByUser(getContext())) {
+ if (!VideoUtils.hasCameraPermissionAndShownPrivacyToast(getContext())) {
videoCallScreenDelegate.onCameraPermissionDialogShown();
if (!VideoUtils.hasCameraPermission(getContext())) {
requestPermissions(new String[] {permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
} else {
- CameraPermissionDialogFragment.newInstance()
- .show(getChildFragmentManager(), CAMERA_PERMISSION_DIALOG_FRAMENT_TAG);
+ PermissionsUtil.showCameraPermissionToast(getContext());
+ videoCallScreenDelegate.onCameraPermissionGranted();
}
}
}
diff --git a/java/com/android/incallui/video/protocol/VideoCallScreenDelegate.java b/java/com/android/incallui/video/protocol/VideoCallScreenDelegate.java
index e7e69df..55ea23f 100644
--- a/java/com/android/incallui/video/protocol/VideoCallScreenDelegate.java
+++ b/java/com/android/incallui/video/protocol/VideoCallScreenDelegate.java
@@ -37,7 +37,7 @@
void onCameraPermissionGranted();
- boolean shouldShowCameraPermissionDialog();
+ boolean shouldShowCameraPermissionToast();
void onCameraPermissionDialogShown();
diff --git a/java/com/android/incallui/videotech/utils/VideoUtils.java b/java/com/android/incallui/videotech/utils/VideoUtils.java
index 5276540..9dfc687 100644
--- a/java/com/android/incallui/videotech/utils/VideoUtils.java
+++ b/java/com/android/incallui/videotech/utils/VideoUtils.java
@@ -20,12 +20,10 @@
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
-import com.android.dialer.util.DialerUtils;
+import com.android.dialer.util.PermissionsUtil;
public class VideoUtils {
- private static final String PREFERENCE_CAMERA_ALLOWED_BY_USER = "camera_allowed_by_user";
-
public static boolean hasSentVideoUpgradeRequest(@SessionModificationState int state) {
return state == SessionModificationState.WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE
|| state == SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_FAILED
@@ -37,24 +35,12 @@
return state == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST;
}
- public static boolean hasCameraPermissionAndAllowedByUser(@NonNull Context context) {
- return isCameraAllowedByUser(context) && hasCameraPermission(context);
+ public static boolean hasCameraPermissionAndShownPrivacyToast(@NonNull Context context) {
+ return PermissionsUtil.hasCameraPrivacyToastShown(context) && hasCameraPermission(context);
}
public static boolean hasCameraPermission(@NonNull Context context) {
return ContextCompat.checkSelfPermission(context, android.Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED;
}
-
- public static boolean isCameraAllowedByUser(@NonNull Context context) {
- return DialerUtils.getDefaultSharedPreferenceForDeviceProtectedStorageContext(context)
- .getBoolean(PREFERENCE_CAMERA_ALLOWED_BY_USER, false);
- }
-
- public static void setCameraAllowedByUser(@NonNull Context context) {
- DialerUtils.getDefaultSharedPreferenceForDeviceProtectedStorageContext(context)
- .edit()
- .putBoolean(PREFERENCE_CAMERA_ALLOWED_BY_USER, true)
- .apply();
- }
}