Update permissions around showCallScreen.
Change-Id: I297c49f8256df3924217cddc3a0ffbd3dff7accc
diff --git a/src/com/android/telecomm/TelecommServiceImpl.java b/src/com/android/telecomm/TelecommServiceImpl.java
index ca80e8a..9aa4687 100644
--- a/src/com/android/telecomm/TelecommServiceImpl.java
+++ b/src/com/android/telecomm/TelecommServiceImpl.java
@@ -16,21 +16,24 @@
package com.android.telecomm;
-import com.google.android.collect.Lists;
-
-import com.android.internal.telecomm.ITelecommService;
-
+import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
import android.net.Uri;
+import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.ServiceManager;
+import android.phone.PhoneManager;
import android.telecomm.CallState;
-import android.text.TextUtils;
import android.telecomm.PhoneAccount;
+import android.telecomm.TelecommManager;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telecomm.ITelecommService;
+import com.google.android.collect.Lists;
import java.util.List;
@@ -108,12 +111,16 @@
/** The singleton instance. */
private static TelecommServiceImpl sInstance;
+ private final MainThreadHandler mMainThreadHandler = new MainThreadHandler();
private final CallsManager mCallsManager = CallsManager.getInstance();
private final MissedCallNotifier mMissedCallNotifier;
- private final MainThreadHandler mMainThreadHandler = new MainThreadHandler();
+ private final AppOpsManager mAppOpsManager;
private TelecommServiceImpl(MissedCallNotifier missedCallNotifier) {
mMissedCallNotifier = missedCallNotifier;
+ mAppOpsManager =
+ (AppOpsManager) TelecommApp.getInstance().getSystemService(Context.APP_OPS_SERVICE);
+
publish();
}
@@ -249,18 +256,41 @@
sendRequestAsync(MSG_ACCEPT_RINGING_CALL, 0);
}
+ /**
+ * @see PhoneManager#showCallScreen
+ */
@Override
public void showCallScreen(boolean showDialpad) {
+ enforceReadPermissionOrDefaultDialer();
sendRequestAsync(MSG_SHOW_CALL_SCREEN, showDialpad ? 1 : 0);
}
+ /**
+ * @see PhoneManager#cancelMissedCallsNotification
+ */
@Override
public void cancelMissedCallsNotification() {
+ enforceModifyPermissionOrDefaultDialer();
sendRequestAsync(MSG_CANCEL_MISSED_CALLS_NOTIFICATION, 0);
}
+ /**
+ * @see PhoneManager#handlePinMmi
+ */
+ @Override
+ public boolean handlePinMmi(String dialString) {
+ enforceModifyPermissionOrDefaultDialer();
+
+ // Switch identity so that TelephonyManager checks Telecomm's permissions instead.
+ long token = Binder.clearCallingIdentity();
+ boolean retval = getTelephonyManager().handlePinMmi(dialString);
+ Binder.restoreCallingIdentity(token);
+
+ return retval;
+ }
+
//
- // Supporting methods for the ITelephony interface implementation.
+ // Supporting methods for the ITelecommService interface implementation.
//
private void acceptRingingCallInternal() {
@@ -304,15 +334,46 @@
android.Manifest.permission.MODIFY_PHONE_STATE, null);
}
+ private void enforceModifyPermissionOrDefaultDialer() {
+ if (!isDefaultDialerCalling()) {
+ enforceModifyPermission();
+ }
+ }
+
private void enforceReadPermission() {
TelecommApp.getInstance().enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PHONE_STATE, null);
}
+ private void enforceReadPermissionOrDefaultDialer() {
+ if (!isDefaultDialerCalling()) {
+ enforceReadPermission();
+ }
+ }
+
private void showCallScreenInternal(boolean showDialpad) {
CallsManager.getInstance().getInCallController().bringToForeground(showDialpad);
}
+ private boolean isDefaultDialerCalling() {
+ ComponentName defaultDialerComponent = getDefaultPhoneApp();
+ if (defaultDialerComponent != null) {
+ try {
+ mAppOpsManager.checkPackage(
+ Binder.getCallingUid(), defaultDialerComponent.getPackageName());
+ return true;
+ } catch (SecurityException e) {
+ Log.e(TAG, e, "Could not get default dialer.");
+ }
+ }
+ return false;
+ }
+
+ private TelephonyManager getTelephonyManager() {
+ return (TelephonyManager)
+ TelecommApp.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
+ }
+
private void publish() {
Log.d(this, "publish: %s", this);
ServiceManager.addService(SERVICE_NAME, this);