Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0dd9902c authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

App ops: add UI for viewing and controlling ops per-app.

Change-Id: Iadd68cbd429af4d431dcd09b9adacd09c5092ae6
parent 57440190
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2013, 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.
*/
-->
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:scrollbarStyle="@*android:integer/preference_fragment_scrollbarStyle">

    <LinearLayout
        android:id="@+id/all_details"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="5dip"
        android:orientation="vertical">

        <!-- App snippet -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:paddingStart="?android:attr/listPreferredItemPaddingStart"
            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
            android:orientation="vertical">

            <!-- Application snippet label, version and icon -->
            <include
                layout="@layout/manage_applications_item"
                android:id="@+id/app_snippet" />

        </LinearLayout>

        <!-- Operations list -->
        <LinearLayout
            android:id="@+id/operations_section"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
        </LinearLayout>
    </LinearLayout>
</ScrollView>
+71 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2008, 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.
*/
-->

<GridLayout 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">

    <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_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"
        android:layout_gravity="fill_horizontal"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textAlignment="viewStart" />

    <Switch android:id="@+id/switchWidget"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dip"
        android:layout_column="2"
        android:layout_row="0"
        android:layout_rowSpan="2"
        android:padding="8dip"
        android:focusable="false"
        android:clickable="true" />

</GridLayout>
+3 −0
Original line number Diff line number Diff line
@@ -572,6 +572,9 @@
        <item>Write contacts</item>
        <item>Read calls</item>
        <item>Write calls</item>
        <item>Read calendar</item>
        <item>Write calendar</item>
        <item>Wi-Fi scan</item>
    </string-array>
    
    <!-- Titles for the list of long press timeout options. -->
+3 −1
Original line number Diff line number Diff line
@@ -2705,6 +2705,8 @@
    <string name="app_ops_settings">App ops</string>
    <!-- [CHAR LIMIT=NONE] Time label for an operation that is currently running. -->
    <string name="app_ops_running">Running</string>
    <!-- [CHAR LIMIT=NONE] Time label for an operation that has never executed. -->
    <string name="app_ops_never_used">(Never used)</string>

    <!-- [CHAR LIMIT=25] Services settings screen, setting option name for the user to go to the screen to view app storage use -->
    <string name="storageuse_settings_title">Storage use</string>
+37 −10
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -45,9 +46,15 @@ import com.android.settings.applications.AppOpsState.AppOpEntry;
public class AppOpsCategory extends ListFragment implements
        LoaderManager.LoaderCallbacks<List<AppOpEntry>> {

    private static final int RESULT_APP_DETAILS = 1;

    AppOpsState mState;

    // This is the Adapter being used to display the list's data.
    AppListAdapter mAdapter;

    String mCurrentPkgName;

    public AppOpsCategory() {
    }

@@ -115,9 +122,9 @@ public class AppOpsCategory extends ListFragment implements
        List<AppOpEntry> mApps;
        PackageIntentReceiver mPackageObserver;

        public AppListLoader(Context context, AppOpsState.OpsTemplate template) {
        public AppListLoader(Context context, AppOpsState state, AppOpsState.OpsTemplate template) {
            super(context);
            mState = new AppOpsState(context);
            mState = state;
            mTemplate = template;
        }

@@ -236,13 +243,13 @@ public class AppOpsCategory extends ListFragment implements
    public static class AppListAdapter extends ArrayAdapter<AppOpEntry> {
        private final Resources mResources;
        private final LayoutInflater mInflater;
        private final CharSequence[] mOpNames;
        private final AppOpsState mState;

        public AppListAdapter(Context context) {
        public AppListAdapter(Context context, AppOpsState state) {
            super(context, android.R.layout.simple_list_item_2);
            mResources = context.getResources();
            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mOpNames = mResources.getTextArray(R.array.app_ops_names);
            mState = state;
        }

        public void setData(List<AppOpEntry> data) {
@@ -268,13 +275,19 @@ public class AppOpsCategory extends ListFragment implements
            ((ImageView)view.findViewById(R.id.app_icon)).setImageDrawable(
                    item.getAppEntry().getIcon());
            ((TextView)view.findViewById(R.id.app_name)).setText(item.getAppEntry().getLabel());
            ((TextView)view.findViewById(R.id.op_name)).setText(item.getLabelText(mOpNames));
            ((TextView)view.findViewById(R.id.op_name)).setText(item.getLabelText(mState));
            ((TextView)view.findViewById(R.id.op_time)).setText(item.getTimeText(mResources));

            return view;
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mState = new AppOpsState(getActivity());
    }

    @Override public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

@@ -286,7 +299,7 @@ public class AppOpsCategory extends ListFragment implements
        setHasOptionsMenu(true);

        // Create an empty adapter we will use to display the loaded data.
        mAdapter = new AppListAdapter(getActivity());
        mAdapter = new AppListAdapter(getActivity(), mState);
        setListAdapter(mAdapter);

        // Start out with a progress indicator.
@@ -297,9 +310,23 @@ public class AppOpsCategory extends ListFragment implements
        getLoaderManager().initLoader(0, null, this);
    }

    // utility method used to start sub activity
    private void startApplicationDetailsActivity() {
        // start new fragment to display extended information
        Bundle args = new Bundle();
        args.putString(AppOpsDetails.ARG_PACKAGE_NAME, mCurrentPkgName);

        PreferenceActivity pa = (PreferenceActivity)getActivity();
        pa.startPreferencePanel(AppOpsDetails.class.getName(), args,
                R.string.app_ops_settings, null, this, RESULT_APP_DETAILS);
    }
    
    @Override public void onListItemClick(ListView l, View v, int position, long id) {
        // Insert desired behavior here.
        Log.i("LoaderCustom", "Item clicked: " + id);
        AppOpEntry entry = mAdapter.getItem(position);
        if (entry != null) {
            mCurrentPkgName = entry.getAppEntry().getApplicationInfo().packageName;
            startApplicationDetailsActivity();
        }
    }

    @Override public Loader<List<AppOpEntry>> onCreateLoader(int id, Bundle args) {
@@ -308,7 +335,7 @@ public class AppOpsCategory extends ListFragment implements
        if (fargs != null) {
            template = (AppOpsState.OpsTemplate)fargs.getParcelable("template");
        }
        return new AppListLoader(getActivity(), template);
        return new AppListLoader(getActivity(), mState, template);
    }

    @Override public void onLoadFinished(Loader<List<AppOpEntry>> loader, List<AppOpEntry> data) {
Loading