diff options
-rw-r--r-- | res/layout/installed_app_details.xml | 21 | ||||
-rw-r--r-- | res/values/arrays.xml | 10 | ||||
-rw-r--r-- | res/values/strings.xml | 25 | ||||
-rw-r--r-- | src/com/android/settings/CredentialStorage.java | 14 | ||||
-rw-r--r-- | src/com/android/settings/applications/InstalledAppDetails.java | 93 |
5 files changed, 146 insertions, 17 deletions
diff --git a/res/layout/installed_app_details.xml b/res/layout/installed_app_details.xml index 9e1eeb5..df4f718 100644 --- a/res/layout/installed_app_details.xml +++ b/res/layout/installed_app_details.xml @@ -393,6 +393,27 @@ style="?android:attr/listSeparatorTextViewStyle" android:layout_marginTop="8dip" android:text="@string/permissions_label" /> + <TextView android:id="@+id/security_settings_billing_desc" + android:text="@string/security_settings_billing_desc" + android:textAppearance="?android:attr/textAppearanceSmall" + android:paddingTop="6dip" + android:paddingStart="6dip" + android:paddingBottom="6dip" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + <LinearLayout + android:id="@+id/security_settings_billing_list" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + <TextView + android:text="@string/security_settings_premium_sms_desc" /> + <Spinner + android:id="@+id/security_settings_premium_sms_list" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:spinnerMode="dropdown" /> + </LinearLayout> <TextView android:id="@+id/security_settings_desc" android:text="@string/security_settings_desc" android:textAppearance="?android:attr/textAppearanceSmall" diff --git a/res/values/arrays.xml b/res/values/arrays.xml index e699dc2..6b1c3f9 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -746,4 +746,14 @@ <item>2</item> <item>1</item> </string-array> + + <!-- Values for premium SMS permission selector [CHAR LIMIT=30] --> + <string-array name="security_settings_premium_sms_values"> + <!-- Ask user before sending to premium SMS short code. --> + <item>Ask</item> + <!-- Never allow app to send to premium SMS short code. --> + <item>Never allow</item> + <!-- Always allow app to send to premium SMS short code. --> + <item>Always allow</item> + </string-array> </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index b44952b..cc2bb44 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2567,6 +2567,10 @@ <string name="join_many_items_first"><xliff:g id="first_item">%1$s</xliff:g>, <xliff:g id="all_but_first_and_last_item">%2$s</xliff:g></string> <!-- [CHAR_LIMIT=NONE] Format to put the middle items together in a series of 4 or more items in a list --> <string name="join_many_items_middle"><xliff:g id="added_item">%1$s</xliff:g>, <xliff:g id="rest_of_items">%2$s</xliff:g></string> + <!-- Manage applications, individual application info screen, text that appears under the "Permissions" heading after the app has tried to send to a premium SMS. [CHAR LIMIT=50] --> + <string name="security_settings_billing_desc">This app may charge you money:</string> + <!-- Manage applications, text for permission to send to premium SMS short codes. [CHAR LIMIT=40] --> + <string name="security_settings_premium_sms_desc">Send premium SMS</string> <string name="computing_size">Computing\u2026</string> <string name="invalid_size_value">Couldn\'t compute package size.</string> <!-- String displayed when list is empty --> @@ -2997,18 +3001,17 @@ <string name="accessibility_screen_magnification_title">Screen magnification</string> <!-- Summary for the accessibility preference screen to enable screen magnification. [CHAR LIMIT=35] --> <string name="accessibility_screen_magnification_summary"> - When screen magnification is on, you can:\n - \n - Temporary zoom-in: Triple-tap & hold.\n - Toggle permanent zoom state: Triple-tap & release.\n - \n - Adjust zoomed area: Triple-tap & hold to zoom, then drag your finger across the screen.\n - Pan when zoomed-in: Drag two or more fingers across the screen.\n - \n - Adjust zoom level when zoomed-out: Triple-tap & hold to zoom, then drag one or more fingers.\n - Adjust zoom level when zoomed-in: Pinch with two or more fingers.\n - </string> + When screen magnification is on, you can\:\n\n + + Zoom: Triple-tap & hold.\n + Zoom & pan: Triple-tap & hold, then drag your finger.\n + Toggle zoom in or out: Triple tap & release.\n\n + While you\'re zoomed in, you can:\n + + Pan: Drag two or more fingers across the screen.\n + Adjust zoom level: Pinch or expand using two or more fingers. + </string> <!-- Title for the accessibility preference to enable large text. [CHAR LIMIT=35] --> <string name="accessibility_toggle_large_text_preference_title">Large text</string> <!-- Title for the accessibility preference to enable screen magnification. [CHAR LIMIT=35] --> diff --git a/src/com/android/settings/CredentialStorage.java b/src/com/android/settings/CredentialStorage.java index 07b1776..c737c7d 100644 --- a/src/com/android/settings/CredentialStorage.java +++ b/src/com/android/settings/CredentialStorage.java @@ -25,6 +25,7 @@ import android.content.res.Resources; import android.os.AsyncTask; import android.os.Bundle; import android.os.RemoteException; +import android.os.UserHandle; import android.security.Credentials; import android.security.KeyChain.KeyChainConnection; import android.security.KeyChain; @@ -104,17 +105,24 @@ public final class CredentialStorage extends Activity { */ private int mRetriesRemaining = -1; - @Override protected void onResume() { + @Override + protected void onResume() { super.onResume(); + if (UserHandle.myUserId() != UserHandle.USER_OWNER) { + Log.i(TAG, "Cannot install to CredentialStorage as non-primary user"); + finish(); + return; + } + Intent intent = getIntent(); String action = intent.getAction(); if (ACTION_RESET.equals(action)) { new ResetDialog(); } else { - if (ACTION_INSTALL.equals(action) && - "com.android.certinstaller".equals(getCallingPackage())) { + if (ACTION_INSTALL.equals(action) + && "com.android.certinstaller".equals(getCallingPackage())) { mInstallBundle = intent.getExtras(); } // ACTION_UNLOCK also handled here in addition to ACTION_INSTALL diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index 2c1944d..e056f6a 100644 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -16,6 +16,8 @@ package com.android.settings.applications; +import com.android.internal.telephony.ISms; +import com.android.internal.telephony.SmsUsageMonitor; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.applications.ApplicationsState.AppEntry; @@ -66,12 +68,15 @@ import java.util.List; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.AppSecurityPermissions; +import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.Spinner; import android.widget.TextView; /** @@ -96,6 +101,7 @@ public class InstalledAppDetails extends Fragment private IUsbManager mUsbManager; private AppWidgetManager mAppWidgetManager; private DevicePolicyManager mDpm; + private ISms mSmsManager; private ApplicationsState mState; private ApplicationsState.Session mSession; private ApplicationsState.AppEntry mAppEntry; @@ -371,6 +377,7 @@ public class InstalledAppDetails extends Fragment mUsbManager = IUsbManager.Stub.asInterface(b); mAppWidgetManager = AppWidgetManager.getInstance(getActivity()); mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE); + mSmsManager = ISms.Stub.asInterface(ServiceManager.getService("isms")); mCanBeOnSdCardChecker = new CanBeOnSdCardChecker(); } @@ -595,8 +602,43 @@ public class InstalledAppDetails extends Fragment // Security permissions section LinearLayout permsView = (LinearLayout) mRootView.findViewById(R.id.permissions_section); AppSecurityPermissions asp = new AppSecurityPermissions(getActivity(), packageName); - if (asp.getPermissionCount() > 0) { + int premiumSmsPermission = getPremiumSmsPermission(packageName); + // Premium SMS permission implies the app also has SEND_SMS permission, so the original + // application permissions list doesn't have to be shown/hidden separately. The premium + // SMS subsection should only be visible if the app has tried to send to a premium SMS. + if (asp.getPermissionCount() > 0 + || premiumSmsPermission != SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN) { permsView.setVisibility(View.VISIBLE); + } else { + permsView.setVisibility(View.GONE); + } + // Premium SMS permission subsection + TextView securityBillingDesc = (TextView) permsView.findViewById( + R.id.security_settings_billing_desc); + LinearLayout securityBillingList = (LinearLayout) permsView.findViewById( + R.id.security_settings_billing_list); + if (premiumSmsPermission != SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN) { + // Show the premium SMS permission selector + securityBillingDesc.setVisibility(View.VISIBLE); + securityBillingList.setVisibility(View.VISIBLE); + Spinner spinner = (Spinner) permsView.findViewById( + R.id.security_settings_premium_sms_list); + ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity(), + R.array.security_settings_premium_sms_values, + android.R.layout.simple_spinner_item); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(adapter); + // List items are in the same order as SmsUsageMonitor constants, offset by 1. + spinner.setSelection(premiumSmsPermission - 1); + spinner.setOnItemSelectedListener(new PremiumSmsSelectionListener( + packageName, mSmsManager)); + } else { + // Hide the premium SMS permission selector + securityBillingDesc.setVisibility(View.GONE); + securityBillingList.setVisibility(View.GONE); + } + // App permissions subsection + if (asp.getPermissionCount() > 0) { // Make the security sections header visible LinearLayout securityList = (LinearLayout) permsView.findViewById( R.id.security_settings_list); @@ -642,8 +684,6 @@ public class InstalledAppDetails extends Fragment mPackageInfo.applicationInfo.loadLabel(mPm), appListStr)); } } - } else { - permsView.setVisibility(View.GONE); } checkForceStop(); @@ -652,6 +692,42 @@ public class InstalledAppDetails extends Fragment refreshSizeInfo(); return true; } + + private static class PremiumSmsSelectionListener implements AdapterView.OnItemSelectedListener { + private final String mPackageName; + private final ISms mSmsManager; + + PremiumSmsSelectionListener(String packageName, ISms smsManager) { + mPackageName = packageName; + mSmsManager = smsManager; + } + + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, + long id) { + if (position >= 0 && position < 3) { + Log.d(TAG, "Selected premium SMS policy " + position); + setPremiumSmsPermission(mPackageName, (position + 1)); + } else { + Log.e(TAG, "Error: unknown premium SMS policy " + position); + } + } + + @Override + public void onNothingSelected(AdapterView<?> parent) { + // Ignored + } + + private void setPremiumSmsPermission(String packageName, int permission) { + try { + if (mSmsManager != null) { + mSmsManager.setPremiumSmsPermission(packageName, permission); + } + } catch (RemoteException ex) { + // ignored + } + } + } private void resetLaunchDefaultsUi(TextView title, TextView autoLaunchView) { title.setText(R.string.auto_launch_label); @@ -1027,6 +1103,17 @@ public class InstalledAppDetails extends Fragment } } + private int getPremiumSmsPermission(String packageName) { + try { + if (mSmsManager != null) { + return mSmsManager.getPremiumSmsPermission(packageName); + } + } catch (RemoteException ex) { + // ignored + } + return SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN; + } + /* * Method implementing functionality of buttons clicked * @see android.view.View.OnClickListener#onClick(android.view.View) |