DchaService はチャレンジパッドに搭載されているサービス。教材を動かすために必要不可欠なサービスとなっている。
通常rootやsystem権限が必要な機能なども提供されている。
テストアプリ
dcha_state
これは学習環境や通常環境などを示す値で、以下のように定義されている
dcha_stateの値 | 説明 |
---|---|
0 | 初期状態。com.android.settings.intelligence の検索結果から設定が開けるようになる
count_dcha_completed が在る場合。開発者向けオプションは開けない |
1 |
セットアップウィザードを起動したときの値。 セットアップ中にホーム画面に戻ると、QuickStepが"1"である事を確認した後に DchaStateを"0"に戻し、ナビゲーションバーを表示させる。 |
2 | |
3 |
デジチャレモードと呼ばれている。 開発者向けオプションがパスワード無しで開ける。 count_dcha_completed が作成され、ブラウザとQSBと不明なソースからのアプリのインストールが無効化される。 |
変更方法
ADB
BenesseExtension
使用できる関数
独自のパーミッション「jp.co.benesse.dcha.permission.ACCESS_SYSTEM」の使用で以下の関数を使用することができる
DchaService の外部から呼び出せる関数一覧
verifyUpdateImage
名前からupdate.zipの署名検証を行うように見えるがtrueを返すだけの関数になっている
strにはupdate.zipのパスを入れるが機能していない
Log.d("DchaService", "verifyUpdateImage 0001 updateFile:" + str);
return true;
}
copyUpdateImage
/cacheにファイルをコピーする関数。通常system権限以上が必要だがその権限無しでコピー可能。
strにコピー元パス、str2にコピー先パスを入れる。str2は "/cache" で始まるパスでなければならない
FileChannel channel;
FileChannel channel2;
Log.d("DchaService", "copyUpdateImage 0001 srcFile:" + str + " dstFile:" + ((String) str2));
boolean z = false;
if (TextUtils.isEmpty(str) || TextUtils.isEmpty(str2)) {
Log.d("DchaService", "copyUpdateImage 0009");
return false;
} else if (!str2.startsWith("/cache")) {
Log.d("DchaService", "copyUpdateImage 0010");
return false;
} else {
FileChannel fileChannel = null;
try {
try {
try {
File file = new File(str);
File file2 = new File((String) str2);
channel = new FileInputStream(file).getChannel();
try {
channel2 = new FileOutputStream(file2).getChannel();
} catch (FileNotFoundException e) {
e = e;
fileChannel = channel;
str2 = null;
} catch (IOException e2) {
e = e2;
fileChannel = channel;
str2 = null;
} catch (Exception e3) {
e = e3;
fileChannel = channel;
str2 = null;
} catch (Throwable th) {
th = th;
fileChannel = channel;
str2 = 0;
}
} catch (IOException e4) {
}
try {
channel.transferTo(0L, channel.size(), channel2);
z = true;
Log.d("DchaService", "copyUpdateImage 0005");
if (channel != null) {
Log.d("DchaService", "copyUpdateImage 0006");
try {
channel.close();
} catch (IOException e5) {
}
}
} catch (FileNotFoundException e6) {
str2 = channel2;
e = e6;
fileChannel = channel;
Log.e("DchaService", "copyUpdateImage 0002", e);
Log.d("DchaService", "copyUpdateImage 0005");
if (fileChannel != null) {
Log.d("DchaService", "copyUpdateImage 0006");
try {
fileChannel.close();
} catch (IOException e7) {
}
}
if (str2 != null) {
?? r0 = "copyUpdateImage 0007";
Log.d("DchaService", "copyUpdateImage 0007");
str2.close();
fileChannel = r0;
str2 = str2;
}
Log.d("DchaService", "copyUpdateImage 0008 return:" + z);
return z;
} catch (IOException e8) {
str2 = channel2;
e = e8;
fileChannel = channel;
Log.e("DchaService", "copyUpdateImage 0003", e);
Log.d("DchaService", "copyUpdateImage 0005");
if (fileChannel != null) {
Log.d("DchaService", "copyUpdateImage 0006");
try {
fileChannel.close();
} catch (IOException e9) {
}
}
if (str2 != null) {
?? r02 = "copyUpdateImage 0007";
Log.d("DchaService", "copyUpdateImage 0007");
str2.close();
fileChannel = r02;
str2 = str2;
}
Log.d("DchaService", "copyUpdateImage 0008 return:" + z);
return z;
} catch (Exception e10) {
str2 = channel2;
e = e10;
fileChannel = channel;
Log.e("DchaService", "copyUpdateImage 0004", e);
Log.d("DchaService", "copyUpdateImage 0005");
if (fileChannel != null) {
Log.d("DchaService", "copyUpdateImage 0006");
try {
fileChannel.close();
} catch (IOException e11) {
}
}
if (str2 != null) {
?? r03 = "copyUpdateImage 0007";
Log.d("DchaService", "copyUpdateImage 0007");
str2.close();
fileChannel = r03;
str2 = str2;
}
Log.d("DchaService", "copyUpdateImage 0008 return:" + z);
return z;
} catch (Throwable th2) {
str2 = channel2;
th = th2;
fileChannel = channel;
Log.d("DchaService", "copyUpdateImage 0005");
if (fileChannel != null) {
Log.d("DchaService", "copyUpdateImage 0006");
try {
fileChannel.close();
} catch (IOException e12) {
}
}
if (str2 != 0) {
Log.d("DchaService", "copyUpdateImage 0007");
try {
str2.close();
} catch (IOException e13) {
}
}
throw th;
}
} catch (FileNotFoundException e14) {
e = e14;
str2 = null;
} catch (IOException e15) {
e = e15;
str2 = null;
} catch (Exception e16) {
e = e16;
str2 = null;
} catch (Throwable th3) {
th = th3;
str2 = 0;
}
if (channel2 != null) {
String str3 = "DchaService";
?? r04 = "copyUpdateImage 0007";
Log.d("DchaService", "copyUpdateImage 0007");
channel2.close();
fileChannel = r04;
str2 = str3;
}
Log.d("DchaService", "copyUpdateImage 0008 return:" + z);
return z;
} catch (Throwable th4) {
th = th4;
}
}
}
/cache 以外(/data など)にアクセスしたい場合は、/cache/../data のように、"/cache/../'からパスを指定する。
rebootPad
タブレットを再起動させる関数
i引数には再起動モード、strにはファイルパスを入れて使用する。
再起動モードはiの値に応じて変化し、0=通常再起動 1=初期化 2=パッケージのインストールを行う。
0, 1の場合は str に null を投げる。
Log.d("DchaService", "rebootPad 0001 rebootMode:" + i + " srcFile:" + str);
try {
PowerManager powerManager = (PowerManager) DchaService.this.getSystemService("power");
switch (i) {
case 0:
Log.d("DchaService", "rebootPad 0002");
powerManager.reboot(null);
break;
case 1:
Log.d("DchaService", "rebootPad 0003");
RecoverySystem.rebootWipeUserData(DchaService.this.getBaseContext());
break;
case 2:
Log.d("DchaService", "rebootPad 0004");
if (str != null) {
RecoverySystem.installPackage(DchaService.this.getBaseContext(), new File(str));
break;
}
break;
default:
Log.d("DchaService", "rebootPad 0005");
break;
}
Log.d("DchaService", "rebootPad 0007");
} catch (Exception e) {
Log.e("DchaService", "rebootPad 0006", e);
throw new RemoteException();
}
}
setDefaultPreferredHomeApp
ホームアプリを設定する関数
str引数にはパッケージ名を入れる
try {
Log.d("DchaService", "setDefalutPreferredHomeApp 0001 packageName:" + str);
PackageManager packageManager = DchaService.this.getPackageManager();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_MAIN);
intentFilter.addCategory(Intent.CATEGORY_HOME);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.addCategory(Intent.CATEGORY_DEFAULT);
List<ResolveInfo> queryIntentActivities = packageManager.queryIntentActivities(intent, 0);
ArrayList arrayList = new ArrayList();
ComponentName componentName = null;
for (ResolveInfo resolveInfo : queryIntentActivities) {
String str2 = resolveInfo.activityInfo.applicationInfo.packageName;
String str3 = resolveInfo.activityInfo.name;
Log.d("DchaService", "setDefalutPreferredHomeApp packName:" + str2);
Log.d("DchaService", "setDefalutPreferredHomeApp activityName:" + str3);
ComponentName componentName2 = new ComponentName(str2, str3);
arrayList.add(componentName2);
if (str2.equalsIgnoreCase(str)) {
Log.d("DchaService", "setDefalutPreferredHomeApp 0002");
Log.d("DchaService", "setDefalutPreferredHomeApp defaultHomeComponentName:" + ((Object) componentName2));
componentName = componentName2;
}
}
ComponentName[] componentNameArr = (ComponentName[]) arrayList.toArray(new ComponentName[arrayList.size()]);
if (componentName != null) {
Log.d("DchaService", "setDefalutPreferredHomeApp 0003");
packageManager.addPreferredActivityAsUser(intentFilter, 1081344, componentNameArr, componentName, 0);
}
Log.d("DchaService", "setDefalutPreferredHomeApp 0005");
} catch (Exception e) {
Log.e("DchaService", "setDefalutPrefferredHomeApp 0004", e);
throw new RemoteException(e.toString());
}
}
clearDefaultPreferredApp
Log.d("DchaService", "clearDefaultPreferredApp 0001 packageName:" + str);
try {
DchaService.this.getPackageManager().clearPackagePreferredActivities(str);
} catch (Exception e) {
Log.e("DchaService", "clearDefaultPreferredApp 0002", e);
throw new RemoteException(e.toString());
}
}
disableADB
adbを無効にする関数
Log.d("DchaService", "disableADB 0001");
Settings.Secure.putInt(DchaService.this.getContentResolver(), "adb_enabled", 0);
}
checkPadRooted
タブレットがroot化されているか確認する関数
false を返すだけなので、実際は意味無い。
Log.d("DchaService", "checkPadRooted 0001");
return false;
}
installApp
アプリをインストールする関数。
Neo/Next では署名チェックが無いので使用できる。
strにapkファイルのパス、iには以下の数値を入れる
2=ダウングレードを許可 その他=ダウングレードを許可しない
HandlerThread handlerThread;
Log.d("DchaService", "installApp 0001 path:" + str + " installFlag:" + i);
try {
try {
PackageInstaller packageInstaller = DchaService.this.getPackageManager().getPackageInstaller();
boolean z = true;
PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(1);
sessionParams.setInstallLocation(1);
if (i != 2) {
z = false;
}
sessionParams.setAllowDowngrade(z);
int createSession = packageInstaller.createSession(sessionParams);
PackageInstaller.Session openSession = packageInstaller.openSession(createSession);
if (openSession == null) {
Log.d("DchaService", "installApp 0002");
return false;
}
handlerThread = new HandlerThread("installAppThread");
try {
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
PackageInstallSessionCallback packageInstallSessionCallback = new PackageInstallSessionCallback();
packageInstaller.registerSessionCallback(packageInstallSessionCallback, handler);
installAppSession(openSession, str);
Intent intent = new Intent("jp.co.benesse.dcha.dchaservice.INSTALL_COMPLETE");
intent.setPackage(DchaService.this.getPackageNameFromPid(Binder.getCallingPid()));
openSession.commit(PendingIntent.getBroadcast(DchaService.this.getBaseContext(), createSession, intent, 0).getIntentSender());
synchronized (packageInstallSessionCallback) {
while (!packageInstallSessionCallback.finished) {
try {
Log.d("DchaService", "installApp 0003");
packageInstallSessionCallback.wait();
} catch (InterruptedException e) {
Log.d("DchaService", "installApp 0004");
}
}
}
Log.d("DchaService", "installApp 0005");
packageInstaller.unregisterSessionCallback(packageInstallSessionCallback);
openSession.close();
Log.d("DchaService", "installApp 0006");
boolean z2 = packageInstallSessionCallback.result;
Log.d("DchaService", "installApp 0008");
handlerThread.quit();
return z2;
} catch (Exception e2) {
e = e2;
Log.e("DchaService", "installApp 0007", e);
throw new RemoteException();
} catch (Throwable th) {
th = th;
if (handlerThread != null) {
Log.d("DchaService", "installApp 0008");
handlerThread.quit();
}
throw th;
}
} catch (Exception e3) {
e = e3;
}
} catch (Throwable th2) {
th = th2;
handlerThread = null;
}
}
uninstallApp
アプリをアンインストールする関数
strにはパッケージ名を入れる。i2は不明。
Log.d("DchaService", "uninstallApp 0001 packageName:" + str + " uninstallFlag:" + i);
try {
String packageNameFromPid = DchaService.this.getPackageNameFromPid(getCallingPid());
DchaService dchaService = DchaService.this;
EmergencyLog.write(dchaService, "ELK002", str + " " + packageNameFromPid);
PackageManager packageManager = DchaService.this.getPackageManager();
int i2 = 2;
if (i == 1) {
Log.d("DchaService", "uninstallApp 0002");
i2 = 3;
} else {
Log.d("DchaService", "uninstallApp 0003");
}
PackageDeleteObserver packageDeleteObserver = new PackageDeleteObserver();
packageManager.deletePackage(str, packageDeleteObserver, i2);
synchronized (packageDeleteObserver) {
while (!packageDeleteObserver.finished) {
try {
packageDeleteObserver.wait();
} catch (InterruptedException e) {
}
}
}
Log.d("DchaService", "uninstallApp 0004");
return packageDeleteObserver.result;
} catch (Exception e2) {
Log.e("DchaService", "uninstallApp 0005", e2);
throw new RuntimeException();
}
}
cancelSetup
セットアップをキャンセルする関数
Log.d("DchaService", "cancelSetup 0001");
DchaService.this.doCancelDigichalized();
}
setSetupStatus
DchaStateと環境変数のDigichalizedStatusを変更する関数
Log.d("DchaService", "setSetupStatus 0001 status:" + i);
PreferenceManager.getDefaultSharedPreferences(DchaService.this).edit().putInt("DigichalizedStatus", i).commit();
Settings.System.putInt(DchaService.this.getContentResolver(), "dcha_state", i);
}
getSetupStatus
DigichalizedStatusを取得する関数
Log.d("DchaService", "getSetupStatus 0001");
int i = PreferenceManager.getDefaultSharedPreferences(DchaService.this).getInt("DigichalizedStatus", -1);
Log.d("DchaService", "getSetupStatus 0002 return:" + i);
return i;
}
setSystemTime
removeTask
sdUnmount
setDefaultParam
getForegroundPackageName
copyFile
外部ストレージにファイルをコピーする関数。相対パスを受け付けずディレクトリトラバーサルができないようにされている。
strがコピー元、str2がコピー先のパス
boolean z;
String canonicalExternalPath;
Log.d("DchaService", "copyFile 0001 srcFilePath:" + str + " dstFilePath:" + str2);
try {
canonicalExternalPath = getCanonicalExternalPath(System.getenv("SECONDARY_STORAGE"));
} catch (Exception e) {
Log.e("DchaService", "copyFile 0006", e);
z = false;
}
if (TextUtils.isEmpty(str) || TextUtils.isEmpty(str2)) {
Log.d("DchaService", "copyFile 0002");
throw new IllegalArgumentException();
}
String canonicalExternalPath2 = getCanonicalExternalPath(str);
String canonicalExternalPath3 = getCanonicalExternalPath(str2);
if (!canonicalExternalPath2.startsWith(canonicalExternalPath) && !canonicalExternalPath3.startsWith(canonicalExternalPath)) {
Log.d("DchaService", "copyFile 0003");
throw new SecurityException("The path is not a external storage.");
}
File file = new File(canonicalExternalPath2);
File file2 = new File(canonicalExternalPath3);
if (file.isFile() && (file2.isDirectory() || file2.isFile() || (!file2.exists() && file2.getParentFile().isDirectory()))) {
Log.d("DchaService", "copyFile 0004");
z = fileCopy(file, file2);
Log.d("DchaService", "copyFile 0007 result:" + z);
return z;
}
Log.d("DchaService", "copyFile 0005");
throw new IllegalArgumentException();
}
deleteFile
getUserCount
isDeviceEncryptionEnabled
hideNavigationBar
"true" で非表示、"false" で表示
コメント
最新を表示する
NG表示方式
NGID一覧