summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanesh M <daneshm90@gmail.com>2016-03-07 15:17:59 -0800
committerDanesh M <daneshm90@gmail.com>2016-03-21 11:44:50 -0700
commita3549a2715e47ce07297315586ea9c5798da2997 (patch)
tree895cfd77ae3684f4e3d1c44410d33826246875a0
parentf5dea70443a1c0643be50cf8058ddbfff477712f (diff)
downloadpackages_apps_Settings-a3549a2715e47ce07297315586ea9c5798da2997.zip
packages_apps_Settings-a3549a2715e47ce07297315586ea9c5798da2997.tar.gz
packages_apps_Settings-a3549a2715e47ce07297315586ea9c5798da2997.tar.bz2
Settings : Add per app internet/data control
CYAN-3976 CRACKLING-834 Change-Id: I13192df837c057b5cadde8f31532e12daaf3c1b0
-rw-r--r--res/layout/app_ops_details_item.xml81
-rw-r--r--res/layout/preference_category_material.xml27
-rw-r--r--res/values/cm_strings.xml6
-rw-r--r--src/com/android/settings/applications/AppOpsDetails.java54
-rw-r--r--src/com/android/settings/privacyguard/AppInfoLoader.java3
-rw-r--r--src/com/android/settings/privacyguard/PrivacyGuardManager.java20
6 files changed, 143 insertions, 48 deletions
diff --git a/res/layout/app_ops_details_item.xml b/res/layout/app_ops_details_item.xml
index eb206ae..beb04f3 100644
--- a/res/layout/app_ops_details_item.xml
+++ b/res/layout/app_ops_details_item.xml
@@ -17,68 +17,62 @@
*/
-->
-<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingTop="8dip"
- android:paddingBottom="8dip"
- android:columnCount="3">
+ android:paddingBottom="8dip">
<ImageView
android:id="@+id/op_icon"
android:layout_width="@android:dimen/app_icon_size"
android:layout_height="@android:dimen/app_icon_size"
- android:layout_column="0"
- android:layout_row="0"
- android:layout_rowSpan="2"
android:layout_marginEnd="8dip"
android:scaleType="centerInside"
android:contentDescription="@null" />
- <TextView
- android:id="@+id/op_name"
- android:layout_column="1"
- android:layout_row="0"
- android:layout_columnSpan="2"
- android:layout_gravity="fill_horizontal"
- android:layout_marginTop="2dip"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textAlignment="viewStart" />
-
- <TextView
- android:id="@+id/op_time"
- android:layout_column="1"
- android:layout_row="1"
+ <LinearLayout
+ android:orientation="vertical"
android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_gravity="fill_horizontal|top"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textAlignment="viewStart" />
+ android:layout_weight="1"
+ android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/op_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="fill_horizontal"
+ android:layout_marginTop="2dip"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textAlignment="viewStart" />
- <TextView
- android:id="@+id/op_counts"
- android:layout_column="1"
- android:layout_row="2"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_gravity="fill_horizontal|top"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textAlignment="viewStart" />
+ <TextView
+ android:id="@+id/op_time"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="fill_horizontal|top"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textAlignment="viewStart" />
+
+ <TextView
+ android:id="@+id/op_counts"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="fill_horizontal|top"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textAlignment="viewStart" />
+ </LinearLayout>
<Spinner
android:id="@+id/spinnerWidget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
+ android:layout_gravity="end"
android:layout_marginStart="8dip"
- android:layout_column="2"
- android:layout_row="0"
- android:layout_rowSpan="3"
android:padding="8dip"
android:focusable="false"
android:entries="@+array/app_ops_permissions" />
@@ -87,14 +81,9 @@
android:id="@+id/switchWidget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
+ android:layout_gravity="end"
android:layout_marginStart="8dip"
- android:layout_column="2"
- android:layout_row="0"
- android:layout_rowSpan="3"
android:padding="8dip"
android:focusable="false"
android:clickable="true" />
-
-
-</GridLayout>
+</LinearLayout>
diff --git a/res/layout/preference_category_material.xml b/res/layout/preference_category_material.xml
new file mode 100644
index 0000000..d528464
--- /dev/null
+++ b/res/layout/preference_category_material.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<!-- Layout used for PreferenceCategory in a PreferenceActivity. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+android:id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dip"
+ android:textAppearance="@*android:style/TextAppearance.Material.Body2"
+ android:textColor="@*android:color/preference_category_text_color"
+ android:paddingStart="?*android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?*android:attr/listPreferredItemPaddingEnd"
+ android:paddingTop="16dip" />
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml
index 1328144..17099ec 100644
--- a/res/values/cm_strings.xml
+++ b/res/values/cm_strings.xml
@@ -1156,4 +1156,10 @@
<string name="battery_info_status_charging_dock_ac">Charging on dock AC</string>
<!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging over Dock USB. -->
<string name="battery_info_status_charging_dock_usb">Charging over dock USB</string>
+
+ <string name="restrict_app_wlan_title">Disable app wifi usage</string>
+ <string name="restrict_app_wlan_summary">Prevent app from using wifi data connection</string>
+ <string name="restrict_app_cellular_title">Disable app cellular usage</string>
+ <string name="restrict_app_cellular_summary">Prevent app from using cellular data connection</string>
+ <string name="privacy_guard_internet_category">Internet</string>
</resources>
diff --git a/src/com/android/settings/applications/AppOpsDetails.java b/src/com/android/settings/applications/AppOpsDetails.java
index 12da8b8..af80367 100644
--- a/src/com/android/settings/applications/AppOpsDetails.java
+++ b/src/com/android/settings/applications/AppOpsDetails.java
@@ -16,6 +16,7 @@
package com.android.settings.applications;
+import android.Manifest;
import android.app.Activity;
import android.app.AppOpsManager;
import android.app.Fragment;
@@ -28,6 +29,7 @@ import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
+import android.net.NetworkPolicyManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
@@ -49,6 +51,9 @@ import com.android.settings.Utils;
import java.util.List;
+import static android.net.NetworkPolicyManager.POLICY_REJECT_ON_DATA;
+import static android.net.NetworkPolicyManager.POLICY_REJECT_ON_WLAN;
+
public class AppOpsDetails extends InstrumentedFragment {
static final String TAG = "AppOpsDetails";
@@ -61,6 +66,7 @@ public class AppOpsDetails extends InstrumentedFragment {
private LayoutInflater mInflater;
private View mRootView;
private LinearLayout mOperationsSection;
+ private NetworkPolicyManager mPolicyManager;
private final int MODE_ALLOWED = 0;
private final int MODE_IGNORED = 1;
@@ -178,9 +184,9 @@ public class AppOpsDetails extends InstrumentedFragment {
entry.getTimeText(res, true));
Spinner sp = (Spinner) view.findViewById(R.id.spinnerWidget);
- sp.setVisibility(View.INVISIBLE);
+ sp.setVisibility(View.GONE);
Switch sw = (Switch) view.findViewById(R.id.switchWidget);
- sw.setVisibility(View.INVISIBLE);
+ sw.setVisibility(View.GONE);
final int switchOp = AppOpsManager.opToSwitch(firstOp.getOp());
int mode = mAppOps.checkOp(switchOp, entry.getPackageOps().getUid(),
@@ -226,9 +232,52 @@ public class AppOpsDetails extends InstrumentedFragment {
}
}
+ if (mPm.checkPermission(Manifest.permission.INTERNET, mPackageInfo.packageName)
+ == PackageManager.PERMISSION_GRANTED) {
+ TextView internetCategory = (TextView) mInflater.inflate(
+ R.layout.preference_category_material, null);
+ internetCategory.setText(R.string.privacy_guard_internet_category);
+ mOperationsSection.addView(internetCategory);
+
+ addInternetSwitch(POLICY_REJECT_ON_WLAN);
+ addInternetSwitch(POLICY_REJECT_ON_DATA);
+ }
+
return true;
}
+ private void addInternetSwitch(final int policy) {
+ // Add internet category permissions
+ final View view = mInflater.inflate(R.layout.app_ops_details_item,
+ mOperationsSection, false);
+ mOperationsSection.addView(view);
+
+ ((TextView)view.findViewById(R.id.op_name)).setText(
+ policy == POLICY_REJECT_ON_DATA ? R.string.restrict_app_cellular_title :
+ R.string.restrict_app_wlan_title);
+ view.findViewById(R.id.op_counts).setVisibility(View.INVISIBLE);
+ view.findViewById(R.id.op_time).setVisibility(View.INVISIBLE);
+ view.findViewById(R.id.spinnerWidget).setVisibility(View.GONE);
+
+ Switch sw = (Switch) view.findViewById(R.id.switchWidget);
+ sw.setChecked((mPolicyManager.getUidPolicy(
+ mPackageInfo.applicationInfo.uid) & policy) != 0);
+ sw.setTag(policy);
+ sw.setVisibility(View.VISIBLE);
+ sw.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() {
+ public void onCheckedChanged(CompoundButton buttonView,
+ boolean isChecked) {
+ if (isChecked) {
+ mPolicyManager.addUidPolicy(mPackageInfo.applicationInfo.uid,
+ policy);
+ } else {
+ mPolicyManager.removeUidPolicy(mPackageInfo.applicationInfo.uid,
+ policy);
+ }
+ }
+ });
+ }
+
private void setIntentAndFinish(boolean finish, boolean appChanged) {
Intent intent = new Intent();
intent.putExtra(ManageApplications.APP_CHG, appChanged);
@@ -245,6 +294,7 @@ public class AppOpsDetails extends InstrumentedFragment {
mPm = getActivity().getPackageManager();
mInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mAppOps = (AppOpsManager)getActivity().getSystemService(Context.APP_OPS_SERVICE);
+ mPolicyManager = NetworkPolicyManager.from(getActivity());
retrieveAppEntry();
diff --git a/src/com/android/settings/privacyguard/AppInfoLoader.java b/src/com/android/settings/privacyguard/AppInfoLoader.java
index 6efd7a5..520bd20 100644
--- a/src/com/android/settings/privacyguard/AppInfoLoader.java
+++ b/src/com/android/settings/privacyguard/AppInfoLoader.java
@@ -15,6 +15,7 @@
*/
package com.android.settings.privacyguard;
+import android.Manifest;
import android.app.AppOpsManager;
import android.content.AsyncTaskLoader;
import android.content.Context;
@@ -104,6 +105,8 @@ import java.util.List;
app.uid = info.applicationInfo.uid;
app.privacyGuardEnabled = mAppOps.getPrivacyGuardSettingForPackage(
app.uid, app.packageName);
+ app.hasInternetPermission = mPm.checkPermission(Manifest.permission.INTERNET,
+ app.packageName) == PackageManager.PERMISSION_GRANTED;
apps.add(app);
}
diff --git a/src/com/android/settings/privacyguard/PrivacyGuardManager.java b/src/com/android/settings/privacyguard/PrivacyGuardManager.java
index adbe8cc..4cc8214 100644
--- a/src/com/android/settings/privacyguard/PrivacyGuardManager.java
+++ b/src/com/android/settings/privacyguard/PrivacyGuardManager.java
@@ -16,7 +16,10 @@
package com.android.settings.privacyguard;
+import android.Manifest;
import android.app.FragmentTransaction;
+import android.content.pm.PackageManager;
+import android.net.NetworkPolicyManager;
import android.view.animation.AnimationUtils;
import android.app.Activity;
import android.app.AlertDialog;
@@ -87,6 +90,7 @@ public class PrivacyGuardManager extends Fragment
// Privacy Guard Fragment
private final static String PRIVACY_GUARD_FRAGMENT_TAG = "privacy_guard_fragment";
+ private NetworkPolicyManager mPolicyManager;
// holder for package data passed into the adapter
public static final class AppInfo {
@@ -95,6 +99,13 @@ public class PrivacyGuardManager extends Fragment
boolean enabled;
boolean privacyGuardEnabled;
int uid;
+ boolean hasInternetPermission;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mPolicyManager = NetworkPolicyManager.from(getActivity());
}
@Override
@@ -280,6 +291,15 @@ public class PrivacyGuardManager extends Fragment
app.privacyGuardEnabled = !app.privacyGuardEnabled;
mAppOps.setPrivacyGuardSettingForPackage(app.uid, app.packageName, app.privacyGuardEnabled);
+ if (app.hasInternetPermission) {
+ if (app.privacyGuardEnabled) {
+ mPolicyManager.addUidPolicy(app.uid, NetworkPolicyManager.POLICY_REJECT_ON_DATA);
+ mPolicyManager.addUidPolicy(app.uid, NetworkPolicyManager.POLICY_REJECT_ON_WLAN);
+ } else {
+ mPolicyManager.removeUidPolicy(app.uid, NetworkPolicyManager.POLICY_REJECT_ON_DATA);
+ mPolicyManager.removeUidPolicy(app.uid, NetworkPolicyManager.POLICY_REJECT_ON_WLAN);
+ }
+ }
mAdapter.notifyDataSetChanged();
}