• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.settings.applications;
17 
18 import static android.os.storage.StorageVolume.ScopedAccessProviderContract.AUTHORITY;
19 import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES;
20 import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES_COLUMNS;
21 import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES_COL_PACKAGE;
22 
23 import android.content.ContentResolver;
24 import android.content.Context;
25 import android.database.Cursor;
26 import android.net.Uri;
27 import android.util.ArraySet;
28 import android.util.Log;
29 
30 import com.android.settingslib.applications.ApplicationsState;
31 import com.android.settingslib.applications.ApplicationsState.AppEntry;
32 import com.android.settingslib.applications.ApplicationsState.AppFilter;
33 
34 import java.util.Set;
35 
36 // TODO(b/72055774): add unit tests
37 public class AppStateDirectoryAccessBridge extends AppStateBaseBridge {
38 
39     private static final String TAG = "DirectoryAccessBridge";
40 
41     // TODO(b/72055774): set to false once feature is ready (or use Log.isLoggable)
42     static final boolean DEBUG = true;
43     static final boolean VERBOSE = true;
44 
AppStateDirectoryAccessBridge(ApplicationsState appState, Callback callback)45     public AppStateDirectoryAccessBridge(ApplicationsState appState, Callback callback) {
46         super(appState, callback);
47     }
48 
49     @Override
loadAllExtraInfo()50     protected void loadAllExtraInfo() { }
51 
52     @Override
updateExtraInfo(AppEntry app, String pkg, int uid)53     protected void updateExtraInfo(AppEntry app, String pkg, int uid) { }
54 
55     public static final AppFilter FILTER_APP_HAS_DIRECTORY_ACCESS = new AppFilter() {
56 
57         private Set<String> mPackages;
58 
59         @Override
60         public void init() {
61             throw new UnsupportedOperationException("Need to call constructor that takes context");
62         }
63 
64         @Override
65         public void init(Context context) {
66             mPackages = null;
67             final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
68                     .authority(AUTHORITY).appendPath(TABLE_PACKAGES).appendPath("*")
69                     .build();
70             try (Cursor cursor = context.getContentResolver().query(providerUri,
71                     TABLE_PACKAGES_COLUMNS, null, null)) {
72                 if (cursor == null) {
73                     Log.w(TAG, "Didn't get cursor for " + providerUri);
74                     return;
75                 }
76                 final int count = cursor.getCount();
77                 if (count == 0) {
78                     if (DEBUG) {
79                         Log.d(TAG, "No packages anymore (was " + mPackages + ")");
80                     }
81                     return;
82                 }
83                 mPackages = new ArraySet<>(count);
84                 while (cursor.moveToNext()) {
85                     mPackages.add(cursor.getString(TABLE_PACKAGES_COL_PACKAGE));
86                 }
87                 if (DEBUG) {
88                     Log.d(TAG, "init(): " + mPackages);
89                 }
90             }
91         }
92 
93 
94         @Override
95         public boolean filterApp(AppEntry info) {
96             return mPackages != null && mPackages.contains(info.info.packageName);
97         }
98     };
99 }
100