SettingsFragment: add option to enable CrossProfileDocumentProvider
This commit is contained in:
parent
202f9ff964
commit
ae0e82712d
|
@ -54,6 +54,7 @@
|
||||||
<!-- When the intent is actually already forwarded to work profile -->
|
<!-- When the intent is actually already forwarded to work profile -->
|
||||||
<action android:name="net.typeblog.shelter.action.START_FILE_SHUTTLE" />
|
<action android:name="net.typeblog.shelter.action.START_FILE_SHUTTLE" />
|
||||||
<action android:name="net.typeblog.shelter.action.START_FILE_SHUTTLE_2" />
|
<action android:name="net.typeblog.shelter.action.START_FILE_SHUTTLE_2" />
|
||||||
|
<action android:name="net.typeblog.shelter.action.SYNCHRONIZE_PREFERENCE" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
@ -89,7 +90,8 @@
|
||||||
android:authorities="net.typeblog.shelter.documents"
|
android:authorities="net.typeblog.shelter.documents"
|
||||||
android:grantUriPermissions="true"
|
android:grantUriPermissions="true"
|
||||||
android:permission="android.permission.MANAGE_DOCUMENTS"
|
android:permission="android.permission.MANAGE_DOCUMENTS"
|
||||||
android:exported="true">
|
android:exported="true"
|
||||||
|
android:enabled="false">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
|
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.content.ServiceConnection;
|
||||||
import net.typeblog.shelter.services.FileShuttleService;
|
import net.typeblog.shelter.services.FileShuttleService;
|
||||||
import net.typeblog.shelter.services.ShelterService;
|
import net.typeblog.shelter.services.ShelterService;
|
||||||
import net.typeblog.shelter.util.LocalStorageManager;
|
import net.typeblog.shelter.util.LocalStorageManager;
|
||||||
|
import net.typeblog.shelter.util.SettingsManager;
|
||||||
|
|
||||||
public class ShelterApplication extends Application {
|
public class ShelterApplication extends Application {
|
||||||
private ServiceConnection mShelterServiceConnection = null;
|
private ServiceConnection mShelterServiceConnection = null;
|
||||||
|
@ -17,6 +18,7 @@ public class ShelterApplication extends Application {
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
LocalStorageManager.initialize(this);
|
LocalStorageManager.initialize(this);
|
||||||
|
SettingsManager.initialize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bindShelterService(ServiceConnection conn, boolean foreground) {
|
public void bindShelterService(ServiceConnection conn, boolean foreground) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import net.typeblog.shelter.services.IFileShuttleService;
|
||||||
import net.typeblog.shelter.services.IFileShuttleServiceCallback;
|
import net.typeblog.shelter.services.IFileShuttleServiceCallback;
|
||||||
import net.typeblog.shelter.util.FileProviderProxy;
|
import net.typeblog.shelter.util.FileProviderProxy;
|
||||||
import net.typeblog.shelter.util.LocalStorageManager;
|
import net.typeblog.shelter.util.LocalStorageManager;
|
||||||
|
import net.typeblog.shelter.util.SettingsManager;
|
||||||
import net.typeblog.shelter.util.Utility;
|
import net.typeblog.shelter.util.Utility;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -51,6 +52,7 @@ public class DummyActivity extends Activity {
|
||||||
// This is a bad experience, so we use two to avoid this.
|
// This is a bad experience, so we use two to avoid this.
|
||||||
public static final String START_FILE_SHUTTLE = "net.typeblog.shelter.action.START_FILE_SHUTTLE";
|
public static final String START_FILE_SHUTTLE = "net.typeblog.shelter.action.START_FILE_SHUTTLE";
|
||||||
public static final String START_FILE_SHUTTLE_2 = "net.typeblog.shelter.action.START_FILE_SHUTTLE_2";
|
public static final String START_FILE_SHUTTLE_2 = "net.typeblog.shelter.action.START_FILE_SHUTTLE_2";
|
||||||
|
public static final String SYNCHRONIZE_PREFERENCE = "net.typeblog.shelter.action.SYNCHRONIZE_PREFERENCE";
|
||||||
|
|
||||||
private static final int REQUEST_INSTALL_PACKAGE = 1;
|
private static final int REQUEST_INSTALL_PACKAGE = 1;
|
||||||
private static final int REQUEST_PERMISSION_EXTERNAL_STORAGE= 2;
|
private static final int REQUEST_PERMISSION_EXTERNAL_STORAGE= 2;
|
||||||
|
@ -69,6 +71,7 @@ public class DummyActivity extends Activity {
|
||||||
// so that we can make sure those are updated with our app
|
// so that we can make sure those are updated with our app
|
||||||
Utility.enforceWorkProfilePolicies(this);
|
Utility.enforceWorkProfilePolicies(this);
|
||||||
Utility.enforceUserRestrictions(this);
|
Utility.enforceUserRestrictions(this);
|
||||||
|
SettingsManager.getInstance().applyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
|
@ -93,6 +96,8 @@ public class DummyActivity extends Activity {
|
||||||
actionFreezeAllInList();
|
actionFreezeAllInList();
|
||||||
} else if (START_FILE_SHUTTLE.equals(intent.getAction()) || START_FILE_SHUTTLE_2.equals(intent.getAction())) {
|
} else if (START_FILE_SHUTTLE.equals(intent.getAction()) || START_FILE_SHUTTLE_2.equals(intent.getAction())) {
|
||||||
actionStartFileShuttle();
|
actionStartFileShuttle();
|
||||||
|
} else if (SYNCHRONIZE_PREFERENCE.equals(intent.getAction())) {
|
||||||
|
actionSynchronizePreference();
|
||||||
} else {
|
} else {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
@ -331,4 +336,15 @@ public class DummyActivity extends Activity {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void actionSynchronizePreference() {
|
||||||
|
String name = getIntent().getStringExtra("name");
|
||||||
|
if (getIntent().hasExtra("boolean")) {
|
||||||
|
LocalStorageManager.getInstance()
|
||||||
|
.setBoolean(name, getIntent().getBooleanExtra("boolean", false));
|
||||||
|
}
|
||||||
|
// TODO: Cases for other types
|
||||||
|
SettingsManager.getInstance().applyAll();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import net.typeblog.shelter.services.IAppInstallCallback;
|
||||||
import net.typeblog.shelter.services.IShelterService;
|
import net.typeblog.shelter.services.IShelterService;
|
||||||
import net.typeblog.shelter.services.KillerService;
|
import net.typeblog.shelter.services.KillerService;
|
||||||
import net.typeblog.shelter.util.LocalStorageManager;
|
import net.typeblog.shelter.util.LocalStorageManager;
|
||||||
|
import net.typeblog.shelter.util.SettingsManager;
|
||||||
import net.typeblog.shelter.util.UriForwardProxy;
|
import net.typeblog.shelter.util.UriForwardProxy;
|
||||||
import net.typeblog.shelter.util.Utility;
|
import net.typeblog.shelter.util.Utility;
|
||||||
|
|
||||||
|
@ -120,6 +121,8 @@ public class MainActivity extends AppCompatActivity {
|
||||||
(dialog, which) -> finish())
|
(dialog, which) -> finish())
|
||||||
.show();
|
.show();
|
||||||
} else {
|
} else {
|
||||||
|
// Initialize the settings
|
||||||
|
SettingsManager.getInstance().applyAll();
|
||||||
// Initialize the app (start by binding the services)
|
// Initialize the app (start by binding the services)
|
||||||
bindServices();
|
bindServices();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,22 @@ import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.preference.CheckBoxPreference;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||||
|
|
||||||
import net.typeblog.shelter.R;
|
import net.typeblog.shelter.R;
|
||||||
|
import net.typeblog.shelter.util.SettingsManager;
|
||||||
|
|
||||||
public class SettingsFragment extends PreferenceFragmentCompat {
|
public class SettingsFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener {
|
||||||
private static final String SETTINGS_VERSION = "settings_version";
|
private static final String SETTINGS_VERSION = "settings_version";
|
||||||
private static final String SETTINGS_SOURCE_CODE = "settings_source_code";
|
private static final String SETTINGS_SOURCE_CODE = "settings_source_code";
|
||||||
private static final String SETTINGS_BUG_REPORT = "settings_bug_report";
|
private static final String SETTINGS_BUG_REPORT = "settings_bug_report";
|
||||||
|
private static final String SETTINGS_CROSS_PROFILE_FILE_CHOOSER = "settings_cross_profile_file_chooser";
|
||||||
|
|
||||||
|
private SettingsManager mManager = SettingsManager.getInstance();
|
||||||
|
|
||||||
|
private CheckBoxPreference mPrefCrossProfileFileChooser = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreatePreferences(Bundle bundle, String s) {
|
public void onCreatePreferences(Bundle bundle, String s) {
|
||||||
|
@ -32,6 +39,11 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
||||||
.setOnPreferenceClickListener(this::openSummaryUrl);
|
.setOnPreferenceClickListener(this::openSummaryUrl);
|
||||||
findPreference(SETTINGS_BUG_REPORT)
|
findPreference(SETTINGS_BUG_REPORT)
|
||||||
.setOnPreferenceClickListener(this::openSummaryUrl);
|
.setOnPreferenceClickListener(this::openSummaryUrl);
|
||||||
|
|
||||||
|
// === Interactions ===
|
||||||
|
mPrefCrossProfileFileChooser = (CheckBoxPreference) findPreference(SETTINGS_CROSS_PROFILE_FILE_CHOOSER);
|
||||||
|
mPrefCrossProfileFileChooser.setChecked(mManager.getCrossProfileFileChooserEnabled());
|
||||||
|
mPrefCrossProfileFileChooser.setOnPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean openSummaryUrl(Preference pref) {
|
private boolean openSummaryUrl(Preference pref) {
|
||||||
|
@ -40,4 +52,14 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newState) {
|
||||||
|
if (preference == mPrefCrossProfileFileChooser) {
|
||||||
|
mManager.setCrossProfileFileChooserEnabled((boolean) newState);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ public class LocalStorageManager {
|
||||||
public static final String PREF_IS_SETTING_UP = "is_setting_up";
|
public static final String PREF_IS_SETTING_UP = "is_setting_up";
|
||||||
public static final String PREF_HAS_SETUP = "has_setup";
|
public static final String PREF_HAS_SETUP = "has_setup";
|
||||||
public static final String PREF_AUTO_FREEZE_LIST_WORK_PROFILE = "auto_freeze_list_work_profile";
|
public static final String PREF_AUTO_FREEZE_LIST_WORK_PROFILE = "auto_freeze_list_work_profile";
|
||||||
|
public static final String PREF_CROSS_PROFILE_FILE_CHOOSER = "cross_profile_file_chooser";
|
||||||
|
|
||||||
private static final String LIST_DIVIDER = ",";
|
private static final String LIST_DIVIDER = ",";
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package net.typeblog.shelter.util;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
|
||||||
|
import net.typeblog.shelter.ui.DummyActivity;
|
||||||
|
|
||||||
|
public class SettingsManager {
|
||||||
|
private static SettingsManager sInstance = null;
|
||||||
|
|
||||||
|
public static void initialize(Context context) {
|
||||||
|
sInstance = new SettingsManager(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SettingsManager getInstance() {
|
||||||
|
return sInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LocalStorageManager mStorage = LocalStorageManager.getInstance();
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
private SettingsManager(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syncSettingsToProfileBool(String name, boolean value) {
|
||||||
|
Intent intent = new Intent(DummyActivity.SYNCHRONIZE_PREFERENCE);
|
||||||
|
intent.putExtra("name", name);
|
||||||
|
intent.putExtra("boolean", value);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
Utility.transferIntentToProfile(mContext, intent);
|
||||||
|
mContext.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce all settings
|
||||||
|
public void applyAll() {
|
||||||
|
applyCrossProfileFileChooser();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and apply the enabled state of the cross profile file chooser
|
||||||
|
public void applyCrossProfileFileChooser() {
|
||||||
|
boolean enabled = mStorage.getBoolean(LocalStorageManager.PREF_CROSS_PROFILE_FILE_CHOOSER);
|
||||||
|
mContext.getPackageManager().setComponentEnabledSetting(
|
||||||
|
new ComponentName(mContext, CrossProfileDocumentsProvider.class),
|
||||||
|
enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||||
|
PackageManager.DONT_KILL_APP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the enabled state of the cross profile file chooser
|
||||||
|
public void setCrossProfileFileChooserEnabled(boolean enabled) {
|
||||||
|
mStorage.setBoolean(LocalStorageManager.PREF_CROSS_PROFILE_FILE_CHOOSER, enabled);
|
||||||
|
applyCrossProfileFileChooser();
|
||||||
|
syncSettingsToProfileBool(LocalStorageManager.PREF_CROSS_PROFILE_FILE_CHOOSER, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the enabled state of the cross profile file chooser
|
||||||
|
public boolean getCrossProfileFileChooserEnabled() {
|
||||||
|
return mStorage.getBoolean(LocalStorageManager.PREF_CROSS_PROFILE_FILE_CHOOSER);
|
||||||
|
}
|
||||||
|
}
|
|
@ -116,6 +116,11 @@ public class Utility {
|
||||||
new IntentFilter(DummyActivity.START_FILE_SHUTTLE_2),
|
new IntentFilter(DummyActivity.START_FILE_SHUTTLE_2),
|
||||||
DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
|
DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
|
||||||
|
|
||||||
|
manager.addCrossProfileIntentFilter(
|
||||||
|
adminComponent,
|
||||||
|
new IntentFilter(DummyActivity.SYNCHRONIZE_PREFERENCE),
|
||||||
|
DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
|
||||||
|
|
||||||
// Allow ACTION_SEND and ACTION_SEND_MULTIPLE to cross from managed to parent
|
// Allow ACTION_SEND and ACTION_SEND_MULTIPLE to cross from managed to parent
|
||||||
// TODO: Make this configurable
|
// TODO: Make this configurable
|
||||||
IntentFilter actionSendFilter = new IntentFilter();
|
IntentFilter actionSendFilter = new IntentFilter();
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
|
|
||||||
<!-- Settings Options -->
|
<!-- Settings Options -->
|
||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
|
<string name="settings_interaction">Interaction</string>
|
||||||
|
<string name="settings_cross_profile_file_chooser">Cross-profile Documents UI</string>
|
||||||
|
<string name="settings_cross_profile_file_chooser_desc">When enabled, an option will be shown in the system\'s Documents UI (named Files or Downloads on your launcher) and apps that support Documents UI to allow browsing / viewing / picking / copying files in Shelter from main profile and vice-versa.</string>
|
||||||
<string name="settings_about">About</string>
|
<string name="settings_about">About</string>
|
||||||
<string name="settings_version">Version</string>
|
<string name="settings_version">Version</string>
|
||||||
<string name="settings_source_code">Source Code</string>
|
<string name="settings_source_code">Source Code</string>
|
||||||
|
|
|
@ -2,6 +2,16 @@
|
||||||
<android.support.v7.preference.PreferenceScreen
|
<android.support.v7.preference.PreferenceScreen
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<android.support.v7.preference.PreferenceCategory
|
||||||
|
android:title="@string/settings_interaction">
|
||||||
|
|
||||||
|
<android.support.v7.preference.CheckBoxPreference
|
||||||
|
android:key="settings_cross_profile_file_chooser"
|
||||||
|
android:title="@string/settings_cross_profile_file_chooser"
|
||||||
|
android:summary="@string/settings_cross_profile_file_chooser_desc" />
|
||||||
|
|
||||||
|
</android.support.v7.preference.PreferenceCategory>
|
||||||
|
|
||||||
<android.support.v7.preference.PreferenceCategory
|
<android.support.v7.preference.PreferenceCategory
|
||||||
android:title="@string/settings_about">
|
android:title="@string/settings_about">
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue